summaryrefslogblamecommitdiffstats
path: root/list.c
blob: a6e5e83f84e6ceed65ecd279cb0317308ccee039 (plain) (tree)








































                                                                    
                                       
 
                    















































                                                                          

















                                            


















                                                                  




























































                                                          




























                                                   










































































































                                                                              


 








                                                                      
#include "list.h"

struct List* llist_new()
{
	struct List *list=MALLOC( sizeof(struct List) );
	list->first = NULL;
	list->last = NULL;
	list->count = 0;
	return list;
}


struct ListNode* llist_newn( void *ptr )
{
	struct ListNode *node = MALLOC( sizeof( struct ListNode ) );
	node->next = NULL;
	node->val = ptr;
	return node;
}


int llist_length( struct List *list )
{
	int len;
	struct ListNode *node=list->first;
	for ( len=0; node; node=node->next,len++);
	return len;
}


int llist_index( struct List *list, void *ptr )
{
	int index;
	struct ListNode *node = list->first;
	for ( index=0; node; node=node->next, index++)
			if ( node->val == ptr )
				return index;
	return -1;
}


void llist_reverse( struct List *list )
{
	ERROR("\n");
	//abort(0);
}


void llist_append( struct List *list, void *ptr )
{
	//abort(0);
}


void llist_appendn( struct List **list, void *ptr, struct ListNode *node )
{
	//abort(0);
}


void* llist_pop( struct List *list )
{
	struct ListNode *node = list->last;
	struct ListNode *iter = list->first;
	if ( node )
	{
		/*
		if ( node->prev != NULL )
		{
			void *ptr = node->val;
			//node = node->prev;
			//FREE( node->next );
			//node->next = NULL;
			//list->last = node;
			return ptr;
		}
		*/

		while (iter->next != node)
		{
			iter = iter->next;
		}
		void *ptr = node->val;
		FREE(iter->next);
		iter->next = NULL;
		list->last = iter;
		return ptr;

	}
	return NULL;
}

void* llist_popf( struct List *list )
{
	void *ptr = NULL;
	struct ListNode *node = list->first;
	struct ListNode *next;
	if ( node )
	{
		next = node->next;
		
		list->count -= 1;
		list->first = next;
		if ( list->first == NULL )
			list->last = NULL;
		ptr = node->val;
		free( node );
	}
	return ptr;
}

void llist_push( struct List *list, void *ptr )
{
	struct ListNode *node = MALLOC( sizeof(struct ListNode) );
	node->val = ptr;
	node->next = NULL;
	if ( list->last )
	{
		list->last->next = node;
		list->last = node;
	}
	else
	{
		list->first = node;
		list->last = node;
	}
}


void* llist_removen( struct List *l, struct ListNode *ln )
{
	ListNode *ret=NULL;
	ListNode *iter = l->first;
	ListNode *prev_iter = NULL;

	if ( iter == NULL )
		goto result_ready;

	while ( iter->next != NULL )
	{
		if ( iter == ln )
		{
			break;
		}
		prev_iter = iter;
		iter = iter->next;
	}
	ret = iter;
	iter = NULL; //dont use iter anymore pls

	if ( ret != NULL )
	{
		//if first element of list
		//the prev=NULL
		if ( prev_iter == NULL )
		{
			//if only one element in da list?
			
			if ( l->first == l->last )
			{
				l->first = NULL; 
				l->last = NULL;
			} else
			//if more then one element
			{
				l->first = l->first->next;
			}
			ret->next = NULL;
			goto result_ready;
		}

		//if last element of the list
		if ( ret == l->last )
		{
			prev_iter->next = NULL;
			l->last = prev_iter;
			goto result_ready;
		}

		//if in da middle
		prev_iter->next = ((ListNode *)ret)->next;
		((ListNode *)ret)->next = NULL;

		
	}

result_ready:
	return ret;
}


void llist_free( struct List *list )
{
	struct ListNode *node = list->first, *prev;
	
	while ( node != list->last )
	{
		prev = node;
		node = node->next;
		if (prev != NULL)
		{
			FREE( prev->val );
			FREE( prev );
		}
	}
	if ( node )
	{
		if ( node->val )
			FREE( node->val );
		FREE( node );
	}
	list->first = NULL;
	list->last = NULL;
	FREE( list );
	list = NULL;
}

void llist_freen( struct ListNode *node )
{
	ERROR("\n");
}



void llist_sortn( struct List *list, clb_llist_cmp clb_cmp)
{
	int print_list( List *ln )
	{
		if ( ln == NULL ) return;
		char *ptr=NULL;
		ListNode *l = ln->first;

		while ( l != NULL )
		{
			ptr = l->val;
			printf("%s", ptr);
			if ( l->next != NULL )
			{
				printf("(->%s) ",(char*)l->next->val );
			}
			//printf("\n");
			l = l->next;
		}
		printf("\n");

		return 1;
	}

	int print_node( ListNode *n )
	{
		if ( n == NULL ) return;
		while ( n != NULL )
		{
			printf("%s ", (char*)n->val);
			n = n->next;
		}
		printf("\n");
	}


	//creat new empty list and add all elements sorted
	struct ListNode *sorted=NULL, *last=NULL, *get=NULL;

	get = llist_removen( list, list->first );
	sorted = get;
	get = llist_removen( list, list->first );
	 
	while ( get != NULL )
	{
		//add to empty in sorted like place
		struct ListNode *iter = sorted;
		struct ListNode *prev_iter = malloc( sizeof(struct ListNode));
		memset( prev_iter, 0, sizeof(struct ListNode));
		prev_iter->next = iter;
		while ( iter != NULL )
		{
			//there could be that no empty element in da list
			if ( get == NULL ) break;
			if ( clb_cmp( iter->val, get->val ) >= 0 )
			{
				//add to sorted list end if everything is ok
				if ( iter->next == NULL )
				{
					iter->next = get;
					break;
				}
			} else
			{
				prev_iter->next = get;
				prev_iter = get;
				get->next = iter;
				if ( iter == sorted ) 
				{
					sorted = prev_iter;
				}
				iter = prev_iter;

				break;
			}
			prev_iter = iter;
			iter = iter->next;
		}
		get = llist_removen( list, list->first );
	}
	list->first = sorted;
}

int llist_save( struct List *l, clb_llist_save clb_save )
{
	int ret=0, frc=0;
	if ( l == NULL ) return ret;
	if ( clb_save == NULL ) return ret;

	/*
	struct ListNode *iter = llist_first( l );

	while ( iter != NULL )
	{
		clb_save(  );
		iter = iter->next;
	}
	*/
	frc = clb_save( "/tmp/binlist.txt", l );
	if ( frc != 0)
		ret = -1;
	return ret;
}


struct List* llist_load(  clb_llist_load clb_load, const char *fname )
{
	int ret = 0;
	struct List *loaded = NULL;

	ret = clb_load( (char *)fname, (void **)loaded );

	return loaded;
}