OpenCores
URL https://opencores.org/ocsvn/igor/igor/trunk

Subversion Repositories igor

[/] [igor/] [trunk/] [simulator/] [linkedlist.c] - Rev 4

Compare with Previous | Blame | View Log

/*
 * Copyright (c) 2007 The Akuma Project
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * $Id: linkedlist.c 108 2007-05-13 18:47:48Z eirik $
 */
 
#include <stdio.h>
#include <stdlib.h>
 
#include "linkedlist.h"
 
llist_t
llist_make(void)
{
	llist_t llist;
 
	llist = malloc(sizeof *llist);
	if (llist == NULL)
		return NULL;
	llist->head = NULL;
	llist->tail = NULL;
 
	return llist;
}
 
void
llist_destroy(llist_t head)
{
	llist_node_t node, next;
 
	for (node = head->head; node; node = next) {
		next = node->next;
		free(node);
	}
 
	free(head);
}
 
enum llist_add_type {
	HEAD,
	TAIL
};
 
static int
llist_add(llist_t head, void *obj, enum llist_add_type type)
{
	llist_node_t node;
 
	node = malloc(sizeof *node);
	if (node == NULL)
		return 0;
 
	node->next = NULL;
	node->obj = obj;
 
	/* First object added */
	if (head->head == NULL) {
		head->head = node;
		head->tail = node;
	} else if (type == TAIL) {
		head->tail->next = node;
		head->tail = node;
	} else if (type == HEAD) {
		node->next = head->head;
		head->head = node;
	}
 
	return 1;
}
 
int
llist_add_pos(llist_t head, void *obj, int pos)
{
	llist_node_t node, prev, newnode;
	int n;
 
	if (head->head == NULL) {
		return llist_add_head(head, obj);
	}
	newnode = malloc(sizeof *newnode);
	if (newnode == NULL)
		return 0;
	newnode->obj = obj;
	newnode->next = NULL;
 
	node = head->head;
	prev = NULL;
	for(node = head->head, n = 0; n < pos; node = node->next, n++) {
		if (node == NULL) {
			prev->next = newnode;
			head->tail = newnode;
			return 1;
		}
		prev = node;
	}
	if (prev == NULL) {
		head->head = newnode;
		newnode->next = node;
	} else {
		newnode->next = prev->next;
		prev->next = newnode;
	}
 
	return 1;
}
 
int
llist_add_tail(llist_t head, void *obj)
{
	return llist_add(head, obj, TAIL);
}
 
int
llist_add_head(llist_t head, void *obj)
{
	return llist_add(head, obj, HEAD);
}
 
void *
llist_pop(llist_t head)
{
	llist_node_t node;
	void *obj;
 
	if (head->head == NULL)
		return NULL;
	node = head->head;
	if (node->next == NULL) {
		head->head = NULL;
		head->tail = NULL;
	}
	else {
		head->head = node->next;
	}
 
	obj = llist_getobj(node);
	free(node);
	return obj;
}
 
/* zero indexed */
void *
llist_getelem(llist_t head, int num)
{
	int i;
	llist_node_t node;
 
	i = 0;
	LLIST_FOREACH(head, node) {
		if (i == num)
			return llist_getobj(node);
		i++;
	}
	return NULL;
}
 
void *
llist_getobj(llist_node_t node)
{
	return node->obj;
}
 
int
llist_empty(llist_t head)
{
	return (head->head == NULL);
}
 
llist_t
llist_copy(llist_t old)
{
	llist_t new;
	llist_node_t node;
 
	new = llist_make();
	if (new == NULL)
		return NULL;
	LLIST_FOREACH(old, node) {
		if (!llist_add_tail(new, llist_getobj(node))) {
			llist_destroy(new);
			return NULL;
		}
	}
 
	return new;
}
 
int
llist_insert_list_head(llist_t head, llist_t add)
{
	llist_t copy = llist_copy(add);
	llist_node_t node;
 
	if (copy == NULL)
		return 0;
	if (head->head == NULL) {
		head->head = copy->head;
		head->tail = copy->tail;
	} else {
		node = head->head;
		head->head = copy->head; 
		copy->tail->next = node;
	}
	free(copy);
 
	return 1;
}
 
int
llist_size(llist_t head)
{
	int n;
	llist_node_t node;
 
	n = 0;
	LLIST_FOREACH(head, node)
		n++;
 
	return n;
}
 
void
llist_remove_elem(llist_t list, int n)
{
	llist_node_t cur, prev;
	int i;
 
	if (list->head == NULL)
		return;
 
	prev = NULL;
	for(cur = list->head, i = 0; cur; cur = cur->next, i++) {
		if (i == n) {
			if (cur == list->head) {
				list->head = cur->next;
			}
			if (cur == list->tail) {
				list->tail = prev;
			}
			prev->next = cur->next;
			free(cur);
			return;
		}
		i++;
		prev = cur;
	}
}
 
int
llist_insert_list(llist_t list, llist_t newlist, int pos)
{
	llist_node_t node;
	int n;
 
	n = pos;
	LLIST_FOREACH(newlist, node) {
		if (!llist_add_pos(list, llist_getobj(node), n++))
			return 0;
	}
 
	return 1;
}
 
#ifdef TEST_LINKEDLIST
 
int
main(void)
{
	llist_t head;
	llist_node_t node;
 
	if ((head = llist_make()) == NULL) {
		fprintf(stderr, "Unable to make linked list\n");
		exit(1);
	}
 
	printf("Add1: %d\n", llist_add_tail(head, "eirik"));
	printf("Add2: %d\n", llist_add_tail(head, "akuma"));
	printf("Add3: %d\n", llist_add_head(head, "jeroen"));
 
	LLIST_FOREACH(head, node) {
		printf("Got: %s\n", llist_getobj(node));
	}
 
	llist_destroy(head);
 
	return 0;
}
 
#endif /* TEST_LINKEDLIST */
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.