/*
 * linked_list.c: A generic linked list implementation
 *
 */

#include "linked_list.h"

void *node_insert(struct node **head_ref, void *new_data, size_t size)
{
	struct node *new_node = NULL;
	void *data = NULL;

	/* Allocate memory for node. */
	if (!(new_node = malloc(sizeof *new_node)))
		return NULL;

	if (!(data = malloc(size))) {
		free(new_node);
		return NULL;
	}

	/* Copy contents of new_data to newly allocated memory. */
	memmove(data, new_data, size);

	/* Update references */
	new_node->data = data;
	new_node->next = (*head_ref);
	new_node->prev = NULL;

	if (*head_ref)
		(*head_ref)->prev = new_node;

	/* Change head pointer as new node is added at the beginning */
	(*head_ref) = new_node;

	return new_node;
}

void node_remove(struct node **head_ref, struct node *del)
{
	if (*head_ref == NULL || del == NULL)
		return;

	if (*head_ref == del)
		*head_ref = del->next;

	/* Disconnect the node */
	if (del->next)
		del->next->prev = del->prev;
	if (del->prev)
		del->prev->next = del->next;

	/* Release the allocate memory */
	free(del->data);
	free(del);
}
