Gamestudio Links
Zorro Links
Newest Posts
freewhyblogelsewhere
by 9489cpjf. 06/03/24 06:06
AlpacaZorroPlugin v1.3.0 Released
by kzhao. 05/22/24 13:41
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
1 registered members (AndrewAMD), 1,301 guests, and 9 spiders.
Key: Admin, Global Mod, Mod
Newest Members
AemStones, LucasJoshua, Baklazhan, Hanky27, firatv
19056 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Updated C-Link library.. #390466
12/30/11 19:37
12/30/11 19:37
Joined: Aug 2003
Posts: 902
Van Buren, Ar
Gordon Offline OP
User
Gordon  Offline OP
User

Joined: Aug 2003
Posts: 902
Van Buren, Ar
header
Code:
//*@@Module User CLinkLib3 ***************************************************
// Name:
//    CLinkLib3
//
// Author:
//    Gordon Tackett
//
// Date:
//		01/10/2010
//
// Copyright:
//		copyright 2008, 2010 by Westmarch Studios. All rights reserved.
//		This file may be freely copied as long as the copyright statement
//		remains unchanged. This module is open source. All changes and
//		modifications must be shared in source form. Please post modifications
//		to http://forums.westmarch.com
//
//		Can download lastest copy from 
//			http://download.westmarch.com/public/source/clinklib.zip
//
// Description:
//		This module is used to manage the C_LINK structure and provide access
//		methods for its members. As long as the C_LINK item is the FIRST item
//		in the structure these methods can be used to manage it.
//
// History:
//		12/27/2011		Added AddInsertionSort and InsertionSort
//	   10/15/2011     Added ForEachXWait functions
//    01/10/2011     Added validation tests and debug tools.
//		05/12/2010		Added list header structure
//		01/06/2009		Added link_rename.
//		01/04/2009		Added last_link.
//		12/20/2008		First public release.    
//
//*@@End**********************************************************************

#ifndef CLINKLIB3_H
#define CLINKLIB3_H

#ifndef acknex_h
#include <acknex.h>
#endif

//@@type CLINK_HEADER --------------------------------------------------------
//
// This structure holds the control information for the C_LINK based linked
// lists. You should not modify this strucure directly but use the CLINKLIB3
// library to access and modify any data in this structure.
//
//@@end ----------------------------------------------------------------------

typedef struct {
#ifdef CLINKLIB3_DEBUG
	long	MagicNumber1;	 // Set this group of 4 numbers to values that 
	long	MagicNumber2;	 // are not likely to be random in memory
	long	MagicNumber3;	 // 
	long	MagicNumber4;	 // 
#endif
	long	NextHandle;		 // index number of the next object (handle)
	C_LINK* Start; 		 // pointer to next object
	C_LINK* Last;  		 // pointer to last object
	long	Count;			 // count of objects in this list
	long	InitDone;
#ifdef CLINKLIB3_DEBUG
	long	MagicNumber5;	 // Set this group of 4 numbers to values that 
	long	MagicNumber6;	 // are not likely to be random in memory
	long	MagicNumber7;	 // 
	long	MagicNumber8;	 // 
#endif
} CLINKLIB3_HEADER;     // object header


//---------------------------------------------------------------------------
//
// debugging protypes
//
//---------------------------------------------------------------------------


#ifdef CLINKLIB3_DEBUG
int CLinkLib3TestMagicNumbers(CLINKLIB3_HEADER* List);
void CLinkLib3SetMagicNumbers(CLINKLIB3_HEADER* List);
void diags(STRING* str);
void diagl(CLINKLIB3_HEADER* List);
void diagn(C_LINK* Node);
#endif


//---------------------------------------------------------------------------
//
// Prototypes
//
//---------------------------------------------------------------------------


void CLinklib3InitList(CLINKLIB3_HEADER* List);
C_LINK* CLinklib3CreateAndName(int Size, char* Name);
void CLinkLib3AddItemEnd(CLINKLIB3_HEADER* List,C_LINK* Item);
void CLinkLib3AddItemStart(CLINKLIB3_HEADER* List,C_LINK* Item);
void CLinkLib3AddItemAfterItem(CLINKLIB3_HEADER* List, C_LINK* PosItem, C_LINK* Item);
void CLinkLib3AddInsertionSort(CLINKLIB3_HEADER* List, C_LINK* Item, void* Sort);
void CLinkLib3InsertionSort(CLINKLIB3_HEADER* List, void* Sort);
void CLinkLib3DeleteItem(CLINKLIB3_HEADER* List, C_LINK* Item);
void CLinkLib3DeleteFirst(CLINKLIB3_HEADER* List);
void CLinkLib3DeleteLast(CLINKLIB3_HEADER* List);
C_LINK* CLinkLib3GetNext(CLINKLIB3_HEADER* List, C_LINK* Item);
C_LINK* CLinkLib3GetPrev(CLINKLIB3_HEADER* List, C_LINK* Item);
int CLinkLib3ForEach(CLINKLIB3_HEADER* List,void* Func);
int CLinkLib3ForEachWait(CLINKLIB3_HEADER* List,void* Func);
int CLinkLib3ForEachP2(CLINKLIB3_HEADER* List,void* Func, var p1, var p2);
int CLinkLib3ForEachP2Wait(CLINKLIB3_HEADER* List,void* Func, var p1, var p2);
int CLinkLib3ForEachP1(CLINKLIB3_HEADER* List,void* Func, var p1);
int CLinkLib3ForEachP1Wait(CLINKLIB3_HEADER* List,void* Func, var p1);
int CLinkLib3ForEachThat(CLINKLIB3_HEADER* List,void* Func, void* Test);
int CLinkLib3ForEachThatWait(CLINKLIB3_HEADER* List,void* Func, void* Test);
C_LINK* CLinkLib3FindByHandle(CLINKLIB3_HEADER* List, int Handle);
C_LINK* CLinkLib3FindByName(CLINKLIB3_HEADER* List, char* Name);
C_LINK* CLinkLib3FindByFunction(CLINKLIB3_HEADER* List, void* func);
int CLinkLib3Reindex(CLINKLIB3_HEADER* List);
int CLinkLib3Rename(C_LINK* Item, char* Name);



#endif



Code:
#define PRAGMA_POINTER

//*@@Module User CLinkLib3 ***************************************************
// Name:
//    CLinkLib3
//
// Author:
//    Gordon Tackett
//
// Date:
//		01/10/2010
//
// Copyright:
//		copyright 2008, 2010 by Westmarch Studios. All rights reserved.
//		This file may be freely copied as long as the copyright statement
//		remains unchanged. This module is open source. All changes and
//		modifications must be shared in source form. Please post modifications
//		to http://forums.westmarch.com
//
//		Can download lastest copy from 
//			http://download.westmarch.com/public/source/clinklib.zip
//
// Description:
//		This module is used to manage the C_LINK structure and provide access
//		methods for its members. As long as the C_LINK item is the FIRST item
//		in the structure these methods can be used to manage it.
//
// History:
//		12/27/2011		Added AddInsertionSort and InsertionSort
//	   10/15/2011     Added ForEachXWait functions
//    01/10/2011     Added validation tests and debug tools.
//		05/12/2010		Added list header structure
//		01/06/2009		Added link_rename.
//		01/04/2009		Added last_link.
//		12/20/2008		First public release.    
//
//*@@End----------------------------------------------------------------------

#ifndef c_link_util_c
#define c_link_util_c

#include <acknex.h>
#include <atypes.h>
#include "assert.c"


//enable: Debug Mode
//help: Activate this for adding the extra code for debugging your application
#define CLINKLIB3_DEBUG

//enable: Debug Mode
//help: Activate this for adding even more code for debugging your application
#define CLINKLIB3_DEBUG_FULL

//enable: Test Code
//help: Activate this for adding the extra code for testing this module
#define CLINKLIB3_TEST

#ifdef CLINKLIB3_TEST
	#ifndef CLINKLIB3_DEBUG_FULL
		#define CLINKLIB3_DEBUG_FULL
	#endif
#endif

#ifdef CLINKLIB3_DEBUG_FULL
	#ifndef CLINKLIB3_DEBUG
		#define CLINKLIB3_DEBUG
	#endif
#endif

#include "clinklib3.h"


#ifdef CLINKLIB3_DEBUG


//@function internal CLinkLib3TestMagicNumbers ------------------------------
//
// Name:
//    CLinkLib3TestMagicNumbers
//
// Description:
//    This functions tests the numbers that seround the CLINKLIB3_HEADER struct
//		for detection of memory overwrite of control structure. Called by all
//		functions that access the header.
//
// Usage:
//		CLinkLib3TestMagicNumbers(&List);
//
// Parameters:
//		# List - pointer to the list control structure
//
// Output:
//		returns 1 if all numbers match and 0 of any number has changed
//
//*@@End----------------------------------------------------------------------
int CLinkLib3TestMagicNumbers(CLINKLIB3_HEADER* List)
{
	assert(List != NULL,"CLinkLib3TestMagicNumbers : List pointer NULL");
	if (List->MagicNumber1 == 0xf1e1c1b1 
	&& List->MagicNumber2 == 0x8292a2b2 
	&& List->MagicNumber3 == 0x73635343 
	&& List->MagicNumber4 == 0x04142434
	&& List->MagicNumber5 == 0xf1e1c1b1 
	&& List->MagicNumber6 == 0x8292a2b2 
	&& List->MagicNumber7 == 0x73635343 
	&& List->MagicNumber8 == 0x04142434)
	{
	   return(1);
	}
	return(0);
}


//@function internal CLinkLib3SetMagicNumbers -------------------------------
//
// Name:
//    CLinkLib3SetMagicNumbers
//
// Description:
//    This functions sets the numbers that seround the CLINKLIB3_HEADER struct
//		for detection of memory overwrite of control structure. Called by all
//		functions that access the header.
//
// Usage:
//		CLinkLib3SetMagicNumbers(&List);
//
// Parameters:
//		# List - pointer to the list control structure
//
// Output:
//		This function does not return a value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3SetMagicNumbers(CLINKLIB3_HEADER* List)
{
	assert(List != NULL,"CLinkLib3SetMagicNumbers : List pointer NULL");
	List->MagicNumber1 = 0xf1e1c1b1; 
	List->MagicNumber2 = 0x8292a2b2; 
	List->MagicNumber3 = 0x73635343; 
	List->MagicNumber4 = 0x04142434;
	List->MagicNumber5 = 0xf1e1c1b1; 
	List->MagicNumber6 = 0x8292a2b2; 
	List->MagicNumber7 = 0x73635343; 
	List->MagicNumber8 = 0x04142434;
}

//@function internal diags ---------------------------------------------------
//
// Name:
//    diags
//
// Description:
//    This function outputs a charage return followed by the requested text 
//		output to the acklog.txt file if diagnostics are enabled. Used interally
//		by other diagnostic functions for output and some functions.
//
// Usage:
//		diags(str);
//
// Parameters:
//		# str - string pointer to output to acklog.txt
//
// Output:
//		This function does not return a value.
//
//*@@End----------------------------------------------------------------------
void diags(STRING* str)
{
	diag("\n");
	diag(str);
}

//@function internal diagl ---------------------------------------------------
//
// Name:
//    diagl
//
// Description:
//    This function outputs all the data from the list head control struct.
//		This function calls diags to output each line. It is called from many
//		functions in this library.
//
// Usage:
//		diagl(&List);
//
// Parameters:
//		# List - pointer to the list control structure
//
// Output:
//		This function does not return a value.
//
//*@@End----------------------------------------------------------------------
void diagl(CLINKLIB3_HEADER* List)
{
	assert(List != NULL,"diagl : List pointer NULL");
	STRING* s = "#256";
	str_printf(s,"List -> %08X ",List);
	diags(s);
	str_printf(s,"    Start -> %08X   Last -> %08X   Count: %4i Next Handle: %4i"
		,List->Start, List->Last, List->Count, List->NextHandle);
	diags(s);
}

//@function internal diagn ---------------------------------------------------
//
// Name:
//    diagn
//
// Description:
//    This function outputs all the data from the C_LINK control struct.
//		This function calls diags to output each line. It is called from many
//		functions in this library.
//
// Usage:
//		diagn(Node);
//
// Parameters:
//		# Node - pointer to the node structure
//
// Output:
//		This function does not return a value.
//
//*@@End----------------------------------------------------------------------
void diagn(C_LINK* Node)
{
	assert(Node != NULL,"diagn : Node pointer NULL");
	STRING* s = "#256";
	str_printf(s,"Node -> %08X ",Node);
	diags(s);
	str_printf(s,"   Next -> %08X   Handle: %4i   Name: %s"
		,Node->next, Node->index, Node->name);
	diags(s);
}


#endif

//@function api CLinklib3InitList -------------------------------------------
//
// Name:
//    CLinklib3InitList
//
// Description:
//    Initialize a CLINKLIB3_HEADER structure to be ready for use with this
//    library of funciton.
//
// Usage:
//		CLinklib3InitList(&List);
//
// Parameters:
//		# List - pointer to the list control structure
//
// Output:
//		This funciton has no return value
//
//*@@End----------------------------------------------------------------------
void CLinklib3InitList(CLINKLIB3_HEADER* List)
{
	assert(List != NULL,"CLinklib3InitList : List pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinklib3InitList: List has been initialized already");
		return;
	}
	else
	{
		diags("CLinklib3InitList");
	}
	CLinkLib3SetMagicNumbers(List);
#endif
	List->NextHandle = 1;
	List->Start = NULL;
	List->Last = NULL;
	List->Count = 0;
	List->InitDone = 42;
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
}


//@function api CLinklib3CreateAndName --------------------------------------
//
// Name:
//    CLinklib3CreateAndName
//
// Description:
//    Allocates memory for a new list element and initializes the element name
//		to the value specified. All other valuse are set to zero. 
//
// Usage:
//		Item = CLinklib3CreateAndName(&List,sizeof(ItemType),Name);
//
// Parameters:
//		# Size - size of the structure you need allocated use sizeof(ItemType)
//		# Name - The null terminated string of the name. can be a STRING*
//			lite-c will convert for you.
//
// Output:
//		This funciton returns a newly allocated pointer to a list item
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinklib3CreateAndName(int Size, char* Name)
{
	C_LINK*	Item;
	
	assert(Size >= sizeof(C_LINK),"CLinklib3CreateAndName : Size to small");
	
#ifdef CLINKLIB3_DEBUG
	//validate input values some.
	if (Size < sizeof(C_LINK))
	{
		diags("CLinklib3CreateAndName: Size smaller than C_LINK!");
		return NULL;
	}
	else
	{
		diags("CLinkLib3CreateAndName");
	}
#endif

	//Allocate a new node
	Item = malloc(Size);
	if (Item != NULL)
	{
		//initialized all the C_LINK members. user must
		//initialize there data after we return.
		Item->name = NULL;
		Item->next = NULL;
		Item->index = 0;
		
		//check for a name
		if (Name != NULL)
		{
			//ok there is a name so allocate space for a copy.
			Item->name = malloc(strlen(Name)+1);
			if (Item->name == NULL)
			{
				#ifdef CLINKLIB3_DEBUG
				//allocation error for the name so free node
				//and return null for a failed node allocation.
				diags("CLinklib3CreateAndName: name allocation failed.");
				#endif
				free(Item);
				Item = NULL;
			} 
			else
			{
				//copy the name to the new space. note this is not
				//a STRING but a char* so we use strcpy and not 
				//str_cpy!
				strcpy(Item->name,Name);
			}
		}		
	}
#ifdef CLINKLIB3_DEBUG
	else
	{
		diags("CLinklib3CreateAndName: node allocation failed.");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(Item);
#endif
#endif
	// return the item pointer or NULL if the allocation failed.
	return(Item);
}


//@function api CLinkLib3AddItemEnd -------------------------------------------
//
// Name:
//    CLinkLib3AddItemEnd
//
// Description:
//    Uses the List header information to find the last item in the list and
//		addes the item pointer to the end of the list.
//
// Usage:
//		CLinkLib3AddItemEnd(&List,Item);
//
// Parameters:
//		# List - pointer to the list control structure
//		# Item - pointer to a C_LINK structure.
//
// Output:
//		This funciton has no return value
//
//*@@End----------------------------------------------------------------------
void CLinkLib3AddItemEnd(CLINKLIB3_HEADER* List,C_LINK* Item)
{
	
	assert(List != NULL,"CLinkLib3AddItemEnd : List pointer NULL");
	assert(Item != NULL,"CLinkLib3AddItemEnd : Item pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3AddItemEnd: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3AddItemEnd");
	}
#endif
	
	Item->index = List->NextHandle;
	List->NextHandle++;
	List->Count++;
	if (List->Last)
	{
		List->Last->next = Item;
	}
	Item->next = NULL;
	List->Last = Item;
	if (List->Start == NULL)
	{
		List->Start = Item;
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
	diagn(Item);
#endif
}


//@function api CLinkLib3AddItemStart ----------------------------------------
//
// Name: 
//    CLinkLib3AddItemStart
//
// Description:
//    Uses the list header to find the start of the list and makes the
//		item's next pointer point to the start of the list then changes
//		the list start pointer to point to the new item.
//
// Usage:
//		CLinkLib3AddItemStart(&list, ItemPtr)	
//
// Parameters:
//		List - a pointer to the list control structure.
//		Item - a pointer to a C_LINK node.
//
// Output:
//		None	
//
//*@@End----------------------------------------------------------------------
void CLinkLib3AddItemStart(CLINKLIB3_HEADER* List,C_LINK* Item)
{

	assert(List != NULL,"CLinkLib3AddItemStart : List pointer NULL");
	assert(Item != NULL,"CLinkLib3AddItemStart : Item pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3AddItemStart: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3AddItemStart");
	}
#endif
	
	Item->index = List->NextHandle;
	List->NextHandle++;
	List->Count++;
	if (List->Last == NULL)
	{
		List->Last = Item;
	}
	Item->next = List->Start;
	List->Start = Item;
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
	diagn(Item);
#endif
}


//@function api CLinkLib3AddItemAfterItem ------------------------------------
//
// Name:
//   CLinkLib3AddItemAfterItem 
//
// Description:
//    Given a list control structure and a pointer to an item this function
//		will put a new item into the list after the specified item. If this
//		item is also the end of the list then the control structure end
//		pointer is updated.
//
// Usage:
//		CLinkLib3AddItemAfterItem(&List, PosItem, Item);
//
// Parameters:
//		List - Pointer to a list control structure
//		PosItem - Pointer to a C_LINK node to add new item after.
//		Item	- Pointer to a C_LINK node to add to list.
//
// Output:
//		None
//
//*@@End----------------------------------------------------------------------
void CLinkLib3AddItemAfterItem(CLINKLIB3_HEADER* List, C_LINK* PosItem, C_LINK* Item)
{
	
	assert(List != NULL,"CLinkLib3AddItemAfterItem : List pointer NULL");
	assert(PosItem != NULL,"CLinkLib3AddItemAfterItem : PosItem pointer NULL");
	assert(Item != NULL,"CLinkLib3AddItemAfterItem : Item pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3AddItemAtItem: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3AddItemAtItem");
	}
#endif
	
	if (PosItem == NULL || PosItem == Item)
	{
		PosItem = List->Last;
	}
	
	Item->index = List->NextHandle;
	Item->next = NULL;
	List->NextHandle++;
	List->Count++;
	if (PosItem)
	{
		Item->next = PosItem->next;
		PosItem->next = Item;
		if (PosItem == List->Last)
		{
			List->Last = Item;
		}
	}
	if (List->Start == NULL)
	{
		List->Start = Item;
		List->Last = Item;
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
	diagn(Item);
#endif
}


//@function api CLinkLib3AddInsertionSort ------------------------------------
//
// Name: 
//    CLinkLib3AddInsertionSort
//
// Description:
//    This function walks the list calling the sort function for each item in
//		the list till it finds the item to insert before.
//
// Usage:
//		CLinkLib3AddInsertionSort(List, Item, Sort)
//
// Parameters:
//		List - pointer to the list control structure
//		Item - pointer to the C_LINK list item to delete.	
//		Sort - pointer to a function that returns true when insert before  
//				current list item.
//
// Output:
//		No return value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3AddInsertionSort(CLINKLIB3_HEADER* List, C_LINK* Item, void* Sort)
{
	C_LINK* CurItem;
	C_LINK* PrevItem;
	int DoSort(C_LINK* Item, C_LINK* CurItem);
	
	assert(List != NULL,"CLinkLib3AddInsertionSort : List pointer NULL");
	assert(Sort != NULL,"CLinkLib3AddInsertionSort : Sort pointer NULL");
	assert(Item != NULL,"CLinkLib3AddInsertionSort : Item pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3AddInsertionSort: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3AddInsertionSort");
	}
#endif

	DoSort = Sort;
	CurItem = List->Start;
	if (DoSort(Item, CurItem)) {
		CLinkLib3AddItemStart(List,Item);
		return;
	}
	PrevItem = CurItem;
	CurItem = CurItem->next;
	while (CurItem != NULL) {
		if (DoSort(Item,CurItem)) {
			CLinkLib3AddItemAfterItem(List, PrevItem, Item);
			return;
		}
		PrevItem = CurItem;
		CurItem = CurItem->next;
	}
	CLinkLib3AddItemEnd(List,Item);
}


//@function api CLinkLib3InsertionSort ---------------------------------------
//
// Name: 
//    CLinkLib3InsertionSort
//
// Description:
//    This function walks the list removeing the head item from the list and
//		calling CLinkLib3AddInsertionSort function for each item in using a 
//		temparary list to add to. When finished it copings the Start and Last
//		pointers form the temparary list to the real list.
//
// Usage:
//		CLinkLib3InsertionSort(List, Item, Sort)
//
// Parameters:
//		List - pointer to the list control structure
//		Sort - pointer to a function that returns true when insert before  
//				current list item.
//
// Output:
//		No return value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3InsertionSort(CLINKLIB3_HEADER* List, void* Sort)
{
	CLINKLIB3_HEADER TmpList;
	C_LINK* CurItem;
	
	assert(List != NULL,"CLinkLib3InsertionSort : List pointer NULL");
	assert(Sort != NULL,"CLinkLib3InsertionSort : Sort pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3InsertionSort: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3InsertionSort");
	}
#endif
	if (List->Start == NULL) {
		return;
	}
	
	CurItem = List->Start;
	List->Start = CurItem->next;
	TmpList.Start = TmpList.Last = CurItem;
	while (List->Start) {
		CurItem = List->Start;
		List->Start = CurItem->next;
		CLinkLib3AddInsertionSort(&TmpList, CurItem, Sort);
	}
	List->Start = TmpList.Start;
	List->Last = TmpList.Last;
}


//@function api CLinkLib3DeleteItem ----------------------------------------
//
// Name: 
//    CLinkLib3DeleteItem
//
// Description:
//    This function removes the item from the list and updates all pointers
//		needed in list control structure. Error message if in debug mode for
//		trying to delete item not in list.
//
// Usage:
//		CLinkLib3DeleteItem(List, Item)
//
// Parameters:
//		List - pointer to the list control structure
//		Item - pointer to the C_LINK list item to delete.	
//
// Output:
//		No return value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3DeleteItem(CLINKLIB3_HEADER* List, C_LINK* Item)
{
	
	assert(List != NULL,"CLinkLib3DeleteItem : List pointer NULL");
	assert(Item != NULL,"CLinkLib3DeleteItem : Item pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3DeleteItem: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3DeleteItem");
	}
#endif
	
	C_LINK* Cur;

	if (List->Start == Item)	
	{
		List->Start = Item->next;
		if (Item->name)
		{
			free(Item->name);
		}
		free(Item);
		List->Count--;
		return;
	}
	for (Cur = List->Start; Cur->next != Item && Cur->next != NULL; Cur = Cur->next)
	   ;
	if (Cur->next = Item)
	{
		Cur->next = Item->next;
		if (Cur->next == NULL)
		{
			List->Last = Cur;
		}
		if (Item->name)
		{
			free(Item->name);
		}
		free(Item);
		List->Count--;
	}
#ifdef CLINKLIB3_DEBUG_FULL
	else
	{
		diags("CLinkLib3DeleteItem: error tried to delete item not in list");
	}
	diagl(List);
#endif
}


//@function api CLinkLib3DeleteFirst -------------------------------------------
//
// Name:
//    CLinkLib3DeleteFirst
//
// Description:
//    This function will delete the first item in the list if one exists. It is
//		not an error to delete from an empty list.
//
// Usage:
//		CLinkLib3DeleteFirst(List);
//
// Parameters:
//		List - pointer to list control structure
//
// Output:
//		No return value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3DeleteFirst(CLINKLIB3_HEADER* List)
{
	
	assert(List != NULL,"CLinkLib3DeleteFirst : List pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3DeleteFirst: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3DeleteFirst");
	}
#endif
	
	C_LINK* cur;
	
	if (List->Start)	
	{
		cur = List->Start;
		List->Start = cur->next;
		if (cur->name)
		{
			free(cur->name);
		}
		free(cur);
		List->Count--;
		return;
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
}


//@function api CLinkLib3DeleteLast -------------------------------------------
//
// Name:
//    CLinkLib3DeleteLast
//
// Description:
//    This function will delete the last item from the list. It is not an error
//		to delete from an empty list.
//
// Usage:
//		CLinkLib3DeleteLast(List);
//
// Parameters:
//		List - pointer to list control structure.
//
// Output:
//		No return value.
//
//*@@End----------------------------------------------------------------------
void CLinkLib3DeleteLast(CLINKLIB3_HEADER* List)
{
	
	assert(List != NULL,"CLinkLib3DeleteLast : List pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3DeleteLast: List has not been initialized yet");
		return;
	}
	else
	{
		diags("CLinkLib3DeleteLast");
	}
#endif
	
	if (List->Start)	
	{
		C_LINK* cur;
		C_LINK* Item;
		
		for (cur = List->Start; cur != NULL && cur->next != List->Last; cur = cur->next);
		if (cur)
		{
			List->Last = cur;
			Item = cur->next;
			cur->next = NULL;
			if (Item->name)
			{
				free(Item->name);
			}
			free(Item);
			List->Count--;
		}
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
}


//@function api CLinkLib3GetNext -------------------------------------------
//
// Name:
//    CLinkLib3GetNext
//
// Description:
//    This function will return the next item in the list after the current
//		item. If the current item is NULL then the first item in the list
//		is returned.
//
// Usage:
//		retval = CLinkLib3GetNext(List, Item);
//
// Parameters:
//		List - pointer to list control structure
//		Item - pointer to current item or NULL for start of list.
//
// Output:
//		Next item in list or NULL for end of list.
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinkLib3GetNext(CLINKLIB3_HEADER* List, C_LINK* Item)
{
	
	assert(List != NULL,"CLinkLib3GetNext : List pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3GetNext: List has not been initialized yet");
		return(NULL);
	}
	else
	{
		diags("CLinkLib3GetNext");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
	if (Item)
	{
		diagn(Item);
	}
#endif
#endif
	if (Item)
	{
		return (Item->next);
	}
	return(List->Start);
}


//@function api CLinkLib3GetPrev -------------------------------------------
//
// Name:
//    CLinkLib3GetPrev
//
// Description:
//    This function returns the previous item in the list or NULL for the
//		start of the list. 
//
// Usage:
//		retval = CLinkLib3GetPrev(List, Item);
//
// Parameters:
//		List - pointer to list control structure.
//		Item - pointer to current item or NULL for end of list.
//
// Output:
//		Previous item in list or NULL for start of list.
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinkLib3GetPrev(CLINKLIB3_HEADER* List, C_LINK* Item)
{
	C_LINK* cur;
	
	assert(List != NULL,"CLinkLib3GetPrev : List pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3GetPrev: List has not been initialized yet");
		return(NULL);
	}
	else
	{
		diags("CLinkLib3GetPrev");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
	if (Item)
	{
		diagn(Item);
	}
#endif
#endif
	
	if (Item)
	{
	   if (Item == List->Start) 
	   {
	      return(NULL);
	   }
		for (cur = List->Start; cur != NULL && cur->next != Item; cur = cur->next)
		   ;
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(cur);
#endif
		return (cur);
	}
	return(List->Last);
}


//@function api CLinkLib3ForEach -------------------------------------------
//
// Name:
//    CLinkLib3ForEach
//
// Description:
//    This function will call the provided function pointer for each item in
//		the list. 
//
// Usage:
//		count = CLinkLib3ForEach(List,Func);
//
// Parameters:
//		List - pointer to list control structure
//		Func - pointer to a function that takes an item as a parameter.
//
// Output:
//		Returns count of items processed.
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEach(CLINKLIB3_HEADER* List,void* Func)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item);
   
	assert(List != NULL,"CLinkLib3ForEach : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEach : Func pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEach: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEach");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
		diagn(Item);
#endif
      cnt += ItemFunc(Item);
   }
   return(cnt);
}


//@function api CLinkLib3ForEachWait ---------------------------------------
//
// Name:
//    CLinkLib3ForEachWait
//
// Description:
//    This function will call the provied function with each item in list
//		as a parameter and wait for this function to finish.
//
// Usage:
//		count = CLinkLib3ForEachWait(List,Func);
//
// Parameters:
//		List - pointer to list control struct.
//		Func - pointer to function that takes a list item as only parameter
//
// Output:
//		Returns count of items processed.
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachWait(CLINKLIB3_HEADER* List,void* Func)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item);
   
	assert(List != NULL,"CLinkLib3ForEachWait : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachWait : Func pointer NULL");
	
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEach: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachWait");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
		diagn(Item);
#endif
      ItemFunc(Item);
      wait_for(ItemFunc);
      cnt++;
   }
   return(cnt);
}


//@function api CLinkLib3ForEachP2 -------------------------------------------
//
// Name:
//    CLinkLib3ForEachP2
//
// Description:
//    This function calls the provided function pointer with each element of
//		the list and also passes the two parameters p1 and p2 to the function.
//
// Usage:
//		count = CLinkLib3ForEachP2(List,Func, p1, p2);
//
// Parameters:
//		List - pointer to list control struct.
//		Func - pointer to function that takes a list item and 2 var parameters
//		P1	- var parameter to be passed to Func when called
//		P2 - Var parameter to be passed to func when called
//
// Output:
//		returns count of items processed
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachP2(CLINKLIB3_HEADER* List,void* Func, var p1, var p2)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item, var p1, var p2);
   
	assert(List != NULL,"CLinkLib3ForEachP2 : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachP2 : Func pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachP2: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachP2");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
		diagn(Item);
#endif
      cnt += ItemFunc(Item,p1,p2);
   }
   return(cnt);
}


//@function api CLinkLib3ForEachP2Wait -------------------------------------------
//
// Name:
//    CLinkLib3ForEachP2Wait
//
// Description:
//    This function calls the provided function pointer with each element of
//		the list and also passes the two parameters p1 and p2 to the function.
//		This function will wait for the provided function to finish with one item
//		before processing the next item.
//
// Usage:
//		count = CLinkLib3ForEachP2Wait(List,Func, p1, p2);
//
// Parameters:
//		List - pointer to list control struct.
//		Func - pointer to function that takes a list item and 2 var parameters
//		P1	- var parameter to be passed to Func when called
//		P2 - Var parameter to be passed to func when called
//
// Output:
//		returns count of items processed
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachP2Wait(CLINKLIB3_HEADER* List,void* Func, var p1, var p2)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item, var p1, var p2);

	assert(List != NULL,"CLinkLib3ForEachP2Wait : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachP2Wait : Func pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachP2Wait: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachP2Wait");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
		diagn(Item);
#endif
      ItemFunc(Item,p1,p2);
      wait_for(ItemFunc);
      cnt++;
   }
   return(cnt);
}


//@function api CLinkLib3ForEachP1 -------------------------------------------
//
// Name:
//    CLinkLib3ForEachP1
//
// Description:
//    This function calls the provided function pointer with each element of
//		the list and also passes the two parameters p1 and p2 to the function.
//
// Usage:
//		count = CLinkLib3ForEachP1(List,Func, p1);
//
// Parameters:
//		List - pointer to list control struct.
//		Func - pointer to function that takes a list item and a var parameter
//		P1	- var parameter to be passed to Func when called
//
// Output:
//		returns count of items processed
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachP1(CLINKLIB3_HEADER* List,void* Func, var p1)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item, var p1);
   
	assert(List != NULL,"CLinkLib3ForEachP1 : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachP1 : Func pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachP1: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachP1");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(Item);
#endif
      cnt += ItemFunc(Item,p1);
   }
   return(cnt);
}


//@function api CLinkLib3ForEachP1Wait -------------------------------------------
//
// Name:
//    CLinkLib3ForEachP1Wait
//
// Description:
//    This function calls the provided function pointer with each element of
//		the list and also passes the two parameters p1 and p2 to the function.
//		This function will wait for the provided function to finish with one item
//		before processing the next item.
//
// Usage:
//		count = CLinkLib3ForEachP1Wait(List,Func, p1);
//
// Parameters:
//		List - pointer to list control struct.
//		Func - pointer to function that takes a list item and a var parameter
//		P1	- var parameter to be passed to Func when called
//
// Output:
//		returns count of items processed
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachP1Wait(CLINKLIB3_HEADER* List,void* Func, var p1)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item, var p1);

	assert(List != NULL,"CLinkLib3ForEachP1Wait : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachP1Wait : Func pointer NULL");

#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachP1Wait: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachP1Wait");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
   cnt = 0;
   ItemFunc = Func;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(Item);
#endif
      cnt += ItemFunc(Item,p1);
      wait_for(ItemFunc);
   }
   return(cnt);
}


//@function api CLinkLib3ForEachThat -------------------------------------------
//
// Name:
//    CLinkLib3ForEachThat
//
// Description:
//    This function will processes each item in a list by first calling
//		The test function and then if test function returns true calling
//		the provided function.
//
// Usage:
//		count = CLinkLib3ForEachThat(List, Func, Test);
//
// Parameters:
//		List - pointert to list control structure
//		Func - pointer to a function that takes a list item as only  parameter.
//		Test - pointer to a function that takes a list item as only parameter
//					and returns true for process and false for not to process.
//
// Output:
//		Count of items processed
//
//	Note:
//		This function could be done with CLinkLib3ForEach but was provided for
//		completeness. 
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachThat(CLINKLIB3_HEADER* List,void* Func, void* Test)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item);
   int ItemTest(C_LINK* Item);
	assert(List != NULL,"CLinkLib3ForEachThat : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachThat : List pointer NULL");
	assert(Test != NULL,"CLinkLib3ForEachThat : List pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachThat: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachThat");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   ItemTest = Test;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
      if (ItemTest(Item))
      {
#ifdef CLINKLIB3_DEBUG_FULL
			diagn(Item);
#endif
	      cnt += ItemFunc(Item);
      }
   }
   return(cnt);
}


//@function api CLinkLib3ForEachThatWait -------------------------------------------
//
// Name:
//    CLinkLib3ForEachThatWait
//
// Description:
//    This function will processes each item in a list by first calling
//		The test function and then if test function returns true calling
//		the provided function. This function will wait for provided function 
//		to finish before calling with next item.
//
// Usage:
//		count = CLinkLib3ForEachThatWait(List, Func, Test);
//
// Parameters:
//		List - pointert to list control structure
//		Func - pointer to a function that takes a list item as only  parameter.
//		Test - pointer to a function that takes a list item as only parameter
//					and returns true for process and false for not to process.
//
// Output:
//		Count of items processed
//
//	Note:
//		This function could be done with CLinkLib3ForEach but was provided for
//		completeness. 
//
//*@@End----------------------------------------------------------------------
int CLinkLib3ForEachThatWait(CLINKLIB3_HEADER* List,void* Func, void* Test)
{
   C_LINK* Item;
   int cnt;
   int ItemFunc(C_LINK* Item);
   int ItemTest(C_LINK* Item);
   
	assert(List != NULL,"CLinkLib3ForEachThatWait : List pointer NULL");
	assert(Func != NULL,"CLinkLib3ForEachThatWait : Func pointer NULL");
	assert(Test != NULL,"CLinkLib3ForEachThatWait : Test pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3ForEachThatWait: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3ForEachThatWait");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   cnt = 0;
   ItemFunc = Func;
   ItemTest = Test;
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
      if (ItemTest(Item))
      {
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(Item);
#endif
	      ItemFunc(Item);
	      wait_for(ItemFunc);
	      cnt++;
      }
   }
   return(cnt);
}


//@function api CLinkLib3FindByHandle -------------------------------------------
//
// Name:
//    CLinkLib3FindByHandle
//
// Description:
//    This function will return the C_LINK item with a handle value of 
//		Handle or NULL if the handle is not found in this list.
//
// Usage:
//		Item = CLinkLib3FindByHandle(List, Handle);
//
// Parameters:
//		List - pointer to a list control structure.
//		Handle - integer value of handle value
//
// Output:
//		Pointer to the item or NULL if item not found.		
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinkLib3FindByHandle(CLINKLIB3_HEADER* List, int Handle)
{
   C_LINK* Item;
	assert(List != NULL,"CLinkLib3FindByHandle : List pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3FindByHandle: List has not been initialized yet");
		return(NULL);
	}
	else
	{
		diags("CLinkLib3FindByHandle");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
      if (Item->index == Handle)
      {
#ifdef CLINKLIB3_DEBUG_FULL
			diagn(Item);
#endif
         return(Item);
      }
   }
   return(NULL);
#ifdef CLINKLIB3_DEBUG
	diags("   Item Not Found!");
#endif
}


//@function api CLinkLib3FindByName -------------------------------------------
//
// Name:
//    CLinkLib3FindByName
//
// Description:
//    This function will return the C_LINK item with a name value of 
//		Name or NULL if the handle is not found in this list.
//
// Usage:
//		Item = CLinkLib3FindByName(List, Name);
//
// Parameters:
//		List - pointer to a list control structure.
//		Name - string value of "name" value
//
// Output:
//		Pointer to the item or NULL if item not found.		
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinkLib3FindByName(CLINKLIB3_HEADER* List, char* Name)
{
   C_LINK* Item;
	assert(List != NULL,"CLinkLib3FindByName : List pointer NULL");
   assert(Name != NULL,"CLinkLib3FindByName : Name pointer is NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3FindByName: List has not been initialized yet");
		return(NULL);
	}
	else
	{
		diags("CLinkLib3FindByName");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
      if (strcmp(Item->name,Name) == 0)
      {
#ifdef CLINKLIB3_DEBUG_FULL
			diagn(Item);
#endif
         return(Item);
      }
   }
   return(NULL);
#ifdef CLINKLIB3_DEBUG
	diags("   Item Not Found!");
#endif
}


//@function api CLinkLib3FindByFunction -------------------------------------------
//
// Name:
//    CLinkLib3FindByFunction
//
// Description:
//    This function will find the first item in the list that matches based on
//		calling the provided function pointer.
//
// Usage:
//		Item = CLinkLib3FindByFunction(List, func)
//
// Parameters:
//		List - List control structure pointer
//		func - function pointer that takes a list item as only parameter
//					returns true for item found.
//
// Output:
//		pointer to the first item matching or NULL for no match found.
//
//*@@End----------------------------------------------------------------------
C_LINK* CLinkLib3FindByFunction(CLINKLIB3_HEADER* List, void* func)
{
   C_LINK* Item;
   int FindFunction(C_LINK* Item);
	assert(List != NULL,"CLinkLib3FindByFunction : List pointer NULL");
	assert(func != NULL,"CLinkLib3FindByFunction : func pointer NULL");
   
   FindFunction = func;
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3FindByHandle: List has not been initialized yet");
		return(NULL);
	}
	else
	{
		diags("CLinkLib3FindByHandle");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   for (Item = List->Start; Item != NULL; Item = Item->next)
   {
      if (func)
      {
         if (FindFunction(Item))
         {
#ifdef CLINKLIB3_DEBUG_FULL
				diagn(Item);
#endif
            return(Item);
         }
      }
   }
   return(NULL);
#ifdef CLINKLIB3_DEBUG
	diags("   Item Not Found!");
#endif
}


//@function api CLinkLib3Reindex -------------------------------------------
//
// Name:
//    CLinkLib3Reindex
//
// Description:
//    This function will renumber all the hanles starting at 1 and proceding 
//		through  end of the list.
//
// Usage:
//		Count = CLinkLib3Reindex(List);
//
// Parameters:
//		List - pointert to list control structure
//
// Output:
//		count of items in list
//
//*@@End----------------------------------------------------------------------
int CLinkLib3Reindex(CLINKLIB3_HEADER* List)
{
   C_LINK* cur;
   int Handle;
	assert(List != NULL,"CLinkLib3Reindex : List pointer NULL");
   
#ifdef CLINKLIB3_DEBUG
	if (!CLinkLib3TestMagicNumbers(List))
	{
		diags("CLinkLib3Reindex: List has not been initialized yet");
		return(0);
	}
	else
	{
		diags("CLinkLib3Reindex");
	}
#ifdef CLINKLIB3_DEBUG_FULL
	diagl(List);
#endif
#endif
   Handle = 0;
   for (cur = List->Start; cur != NULL; cur = cur->next)
   {
      Handle++;
      cur->index = Handle;
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(cur);
#endif
   }
   List->NextHandle = Handle + 1;
   List->Count = Handle + 1;
   return(Handle);
}


//@function api CLinkLib3Rename -------------------------------------------
//
// Name:
//    CLinkLib3Rename
//
// Description:
//    This function will change the string name for the item.
//
// Usage:
//		renamed = CLinkLib3Rename(Item, Name)
//
// Parameters:
//		Item - pointer to an C_LINK Item.
//		Name - pointer to string name.
//
// Output:
//		true if able to rename.
//
//*@@End----------------------------------------------------------------------
int CLinkLib3Rename(C_LINK* Item, char* Name)
{
	char* OldName;
	assert(Item != NULL,"CLinkLib3Rename : Item is NULL");
	
#ifdef CLINKLIB3_DEBUG
   if (Item == NULL)
   {
      diags("CLinkLib3Rename: Item is NULL.");
      return(0);
   }
#endif
   if (Item->name != NULL)
   {
      OldName = Item->name;
      Item->name = NULL;
   }
   if (Name != NULL)
   {
   	Item->name = malloc(strlen(Name) + 1);
   	if (Item->name == NULL)
   	{
			#ifdef CLINKLIB3_DEBUG
				//allocation error for the name so free node
				//and return null for a failed node allocation.
				diags("CLinkLib3Rename: name allocation failed.");
			#endif
			Item->name = OldName;
      	return(0);
   	}
   	strcpy(Item->name,Name);
   	if (OldName != NULL)
   	{
   		free(OldName);
   	}
   }
#ifdef CLINKLIB3_DEBUG_FULL
	diagn(Item);
#endif
   return(1);
}

#endif



//==========================================================================
//
//    					TEST CODE - NOT PART OF API
//
//==========================================================================

#ifdef CLINKLIB3_TEST

CLINKLIB3_HEADER TestList;

typedef struct {
	C_LINK link;
	int	Item;
} node;

int ProcessNode(node* n)
{
	STRING* s = "#256";
	
	diags("ProcessNode");
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}

int ProcessNodeP1(node* n,var p1)
{
	STRING* s = "#256";
	
	diags("ProcessNodeP1");
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}


int ProcessNodeP2(node* n,var p1, var p2)
{
	STRING* s = "#256";
	
	diags("ProcessNodeP2");
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}

int ProcessNodeWait(node* n)
{
	STRING* s = "#256";
	diags("ProcessNodeWait");
	wait(random(10));
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}

int ProcessNodeP1Wait(node* n,var p1)
{
	STRING* s = "#256";
	
	diags("ProcessNodeP1Wait");
	wait(random(10));
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}


int ProcessNodeP2Wait(node* n,var p1, var p2)
{
	STRING* s = "#256";
	
	diags("ProcessNodeP2Wait");
	wait(random(10));
	str_printf(s,"Node %08X - Text  \"%s\" - Index %i - Item %i\n",n,n->link.name,n->link.index,n->Item);
	diags(s);
	return(1);
}

void main(void)
{
	node* testnode;
	node* tmp;
	video_window(NULL,NULL,112,NULL);
	
	CLinklib3InitList(&TestList);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 1");
	testnode->Item = 1;
	tmp = testnode;	
	CLinkLib3AddItemEnd(&TestList, testnode);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 2");
	testnode->Item = 2;	
	CLinkLib3AddItemStart(&TestList, testnode);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 3");
	testnode->Item = 3;	
	CLinkLib3AddItemAfterItem(&TestList,tmp, testnode);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 4");
	testnode->Item = 4;
	CLinkLib3AddItemEnd(&TestList, testnode);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 5");
	testnode->Item = 5;	
	CLinkLib3AddItemStart(&TestList, testnode);
	testnode = CLinklib3CreateAndName(sizeof(node),"test 6");
	testnode->Item = 6;	
	CLinkLib3AddItemEnd(&TestList, testnode);
	
	CLinkLib3ForEach(&TestList, ProcessNode);
	
	CLinkLib3DeleteFirst(&TestList);
	CLinkLib3ForEachP1(&TestList,ProcessNodeP1,0);
	
	CLinkLib3DeleteLast(&TestList);
	CLinkLib3ForEachP2(&TestList,ProcessNodeP2,0,0);
	
	CLinkLib3DeleteItem(&TestList, tmp);
	CLinkLib3ForEachWait(&TestList, ProcessNodeWait);
	wait_for(CLinkLib3ForEachWait);
	
	CLinkLib3Reindex(&TestList);
	CLinkLib3ForEachP1Wait(&TestList,ProcessNodeP1Wait,0);
	wait_for(CLinkLib3ForEachP1Wait);
	
	tmp = CLinkLib3FindByHandle(&TestList, 3);
	CLinkLib3DeleteItem(&TestList, tmp);
	CLinkLib3ForEachP2Wait(&TestList, ProcessNodeP2Wait,0,0);
	wait_for(CLinkLib3ForEachP2Wait);
	
	tmp = CLinkLib3FindByName(&TestList, "test 5");
	CLinkLib3DeleteItem(&TestList, tmp);
	CLinkLib3ForEachP2Wait(&TestList, ProcessNodeP2Wait,0,0);
	wait_for(CLinkLib3ForEachP2Wait);
	
}
#endif




Our new web site:Westmarch Studios
Re: Updated C-Link library.. [Re: Gordon] #390467
12/30/11 19:44
12/30/11 19:44
Joined: Dec 2008
Posts: 1,218
Germany
Rackscha Offline
Serious User
Rackscha  Offline
Serious User

Joined: Dec 2008
Posts: 1,218
Germany
Thanks for this excelent contribution.

But maybe you could use shorter function names?
like CLLAddItemStart?

otherwhiese, this looks perfect laugh


MY Website with news of my projects:
(for example my current
Muliplayer Bomberman,
GenesisPrecompiler for LiteC
and TileMaster, an easy to use Tile editor)
Sparetime-Development

Re: Updated C-Link library.. [Re: Rackscha] #390468
12/30/11 19:45
12/30/11 19:45
Joined: Aug 2003
Posts: 902
Van Buren, Ar
Gordon Offline OP
User
Gordon  Offline OP
User

Joined: Aug 2003
Posts: 902
Van Buren, Ar
Your Welcome :-)


Our new web site:Westmarch Studios

Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1