⛏️ index : haiku.git

/*
 * Copyright 2004-2008, FranΓ§ois Revol, <revol@free.fr>.
 * Distributed under the terms of the MIT License.
 */

#include <KernelExport.h>
#include <OS.h>
#include "lists2.h"

#include <stdio.h>

void *sll_find(long nextoff, void *head, sll_compare_func func, void *id)
{
	void *p = head;
	int count = 5000;
	if (head == NULL)
		return NULL;
	while (p) {
		if (func(p, id) == 0)
			return p;
		p = sll_next(nextoff, p);
		if (!count--) {
			fprintf(stderr, "sll_find: WARNING: 5000 nodes to search ??? looks more of a loop.\n");
			return NULL;
		}
	}
	return NULL;
}

status_t sll_insert_head(long nextoff, void **head, void *item)
{
	void *next = NULL;
	if (head == NULL || item == NULL)
		return EINVAL;
	if (*head)
		next = *head;
	*(void **)(((char *)item)+nextoff) = next;
	*head = item;
	return B_OK;
}

status_t sll_insert_tail(long nextoff, void **head, void *item)
{
	void *p;
	if (head == NULL || item == NULL)
		return EINVAL;

	if (*(void **)(((char *)item)+nextoff)) {
		fprintf(stderr, "sll_insert_tail: WARNING: %p->next NOT NULL\n", item);
		*(void **)(((char *)item)+nextoff) = NULL;
	}

	p = *head;
	if (!p) {
		*head = item;
		return B_OK;
	}
	while (sll_next(nextoff, p))
		p = sll_next(nextoff, p);
	*(void **)(((char *)p)+nextoff) = item;
	return B_OK;
}

void *sll_dequeue_tail(long nextoff, void **head)
{
	void **prev = NULL;
	void *curr = NULL;
	if (head == NULL || *head == NULL)
		return NULL;
	prev = head;
	curr = *head;
	while (sll_next(nextoff, curr)) {
		prev = (void **)(((char *)curr)+nextoff);
		curr = sll_next(nextoff, curr);
	}
	*prev = NULL;
	return curr;
}

status_t sll_remove(long nextoff, void **head, void *item)
{
	void **prev = NULL;
	void *curr = NULL;
	if (head == NULL || *head == NULL || item == NULL)
		return EINVAL;
	prev = head;
	curr = *head;
	while (prev && curr) {
		if (curr == item) {
			*prev = sll_next(nextoff, curr);
			*(void **)(((char *)item)+nextoff) = NULL;
			return B_OK;
		}
		prev = (void **)(((char *)curr)+nextoff);
		curr = sll_next(nextoff, curr);
	}
	return ENOENT;
}

void *sll_next(long nextoff, void *item)
{
	void *next;
	if (!item)
		return NULL;
	next = *(void **)(((char *)item)+nextoff);
	return next;
}