aboutsummaryrefslogtreecommitdiff
path: root/lib/cpluff/kazlib/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cpluff/kazlib/list.c')
-rw-r--r--lib/cpluff/kazlib/list.c935
1 files changed, 0 insertions, 935 deletions
diff --git a/lib/cpluff/kazlib/list.c b/lib/cpluff/kazlib/list.c
deleted file mode 100644
index dc8eed0e63..0000000000
--- a/lib/cpluff/kazlib/list.c
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- * List Abstract Data Type
- * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
- *
- * Free Software License:
- *
- * All rights are reserved by the author, with the following exceptions:
- * Permission is granted to freely reproduce and distribute this software,
- * possibly in exchange for a fee, provided that this copyright notice appears
- * intact. Permission is also granted to adapt this software to produce
- * derivative works, as long as the modified versions carry this copyright
- * notice and additional notices stating that the work has been modified.
- * This source code may be translated into executable form and incorporated
- * into proprietary software; there is no requirement for such software to
- * contain a copyright notice related to this source.
- *
- * $Id: list.c,v 1.19.2.1 2000/04/17 01:07:21 kaz Exp $
- * $Name: kazlib_1_20 $
- */
-
-/*
- * Modified by Johannes Lehtinen in 2006-2007.
- * Included the definition of CP_HIDDEN macro and used it in declarations and
- * definitions to hide Kazlib symbols when building a shared C-Pluff library.
- */
-
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <assert.h>
-#define LIST_IMPLEMENTATION
-#include "list.h"
-
-#define next list_next
-#define prev list_prev
-#define data list_data
-
-#define pool list_pool
-#define fre list_free
-#define size list_size
-
-#define nilnode list_nilnode
-#define nodecount list_nodecount
-#define maxcount list_maxcount
-
-#define list_nil(L) (&(L)->nilnode)
-#define list_first_priv(L) ((L)->nilnode.next)
-#define list_last_priv(L) ((L)->nilnode.prev)
-#define lnode_next(N) ((N)->next)
-#define lnode_prev(N) ((N)->prev)
-
-#ifdef KAZLIB_RCSID
-static const char rcsid[] = "$Id: list.c,v 1.19.2.1 2000/04/17 01:07:21 kaz Exp $";
-#endif
-
-/*
- * Initialize a list object supplied by the client such that it becomes a valid
- * empty list. If the list is to be ``unbounded'', the maxcount should be
- * specified as LISTCOUNT_T_MAX, or, alternately, as -1. The value zero
- * is not permitted.
- */
-
-CP_HIDDEN list_t *list_init(list_t *list, listcount_t maxcount)
-{
- assert (maxcount != 0);
- list->nilnode.next = &list->nilnode;
- list->nilnode.prev = &list->nilnode;
- list->nodecount = 0;
- list->maxcount = maxcount;
- return list;
-}
-
-/*
- * Dynamically allocate a list object using malloc(), and initialize it so that
- * it is a valid empty list. If the list is to be ``unbounded'', the maxcount
- * should be specified as LISTCOUNT_T_MAX, or, alternately, as -1.
- */
-
-CP_HIDDEN list_t *list_create(listcount_t maxcount)
-{
- list_t *new = malloc(sizeof *new);
- if (new) {
- assert (maxcount != 0);
- new->nilnode.next = &new->nilnode;
- new->nilnode.prev = &new->nilnode;
- new->nodecount = 0;
- new->maxcount = maxcount;
- }
- return new;
-}
-
-/*
- * Destroy a dynamically allocated list object.
- * The client must remove the nodes first.
- */
-
-CP_HIDDEN void list_destroy(list_t *list)
-{
- assert (list_isempty(list));
- free(list);
-}
-
-/*
- * Free all of the nodes of a list. The list must contain only
- * dynamically allocated nodes. After this call, the list
- * is empty.
- */
-
-CP_HIDDEN void list_destroy_nodes(list_t *list)
-{
- lnode_t *lnode = list_first_priv(list), *nil = list_nil(list), *tmp;
-
- while (lnode != nil) {
- tmp = lnode->next;
- lnode->next = NULL;
- lnode->prev = NULL;
- lnode_destroy(lnode);
- lnode = tmp;
- }
-
- list_init(list, list->maxcount);
-}
-
-/*
- * Return all of the nodes of a list to a node pool. The nodes in
- * the list must all have come from the same pool.
- */
-
-CP_HIDDEN void list_return_nodes(list_t *list, lnodepool_t *pool)
-{
- lnode_t *lnode = list_first_priv(list), *tmp, *nil = list_nil(list);
-
- while (lnode != nil) {
- tmp = lnode->next;
- lnode->next = NULL;
- lnode->prev = NULL;
- lnode_return(pool, lnode);
- lnode = tmp;
- }
-
- list_init(list, list->maxcount);
-}
-
-/*
- * Insert the node ``new'' into the list immediately after ``this'' node.
- */
-
-CP_HIDDEN void list_ins_after(list_t *list, lnode_t *new, lnode_t *this)
-{
- lnode_t *that = this->next;
-
- assert (new != NULL);
- assert (!list_contains(list, new));
- assert (!lnode_is_in_a_list(new));
- assert (this == list_nil(list) || list_contains(list, this));
- assert (list->nodecount + 1 > list->nodecount);
-
- new->prev = this;
- new->next = that;
- that->prev = new;
- this->next = new;
- list->nodecount++;
-
- assert (list->nodecount <= list->maxcount);
-}
-
-/*
- * Insert the node ``new'' into the list immediately before ``this'' node.
- */
-
-CP_HIDDEN void list_ins_before(list_t *list, lnode_t *new, lnode_t *this)
-{
- lnode_t *that = this->prev;
-
- assert (new != NULL);
- assert (!list_contains(list, new));
- assert (!lnode_is_in_a_list(new));
- assert (this == list_nil(list) || list_contains(list, this));
- assert (list->nodecount + 1 > list->nodecount);
-
- new->next = this;
- new->prev = that;
- that->next = new;
- this->prev = new;
- list->nodecount++;
-
- assert (list->nodecount <= list->maxcount);
-}
-
-/*
- * Delete the given node from the list.
- */
-
-CP_HIDDEN lnode_t *list_delete(list_t *list, lnode_t *del)
-{
- lnode_t *next = del->next;
- lnode_t *prev = del->prev;
-
- assert (list_contains(list, del));
-
- prev->next = next;
- next->prev = prev;
- list->nodecount--;
-
- del->next = del->prev = NULL;
-
- return del;
-}
-
-/*
- * For each node in the list, execute the given function. The list,
- * current node and the given context pointer are passed on each
- * call to the function.
- */
-
-CP_HIDDEN void list_process(list_t *list, void *context,
- void (* function)(list_t *list, lnode_t *lnode, void *context))
-{
- lnode_t *node = list_first_priv(list), *next, *nil = list_nil(list);
-
- while (node != nil) {
- /* check for callback function deleting */
- /* the next node from under us */
- assert (list_contains(list, node));
- next = node->next;
- function(list, node, context);
- node = next;
- }
-}
-
-/*
- * Dynamically allocate a list node and assign it the given piece of data.
- */
-
-CP_HIDDEN lnode_t *lnode_create(void *data)
-{
- lnode_t *new = malloc(sizeof *new);
- if (new) {
- new->data = data;
- new->next = NULL;
- new->prev = NULL;
- }
- return new;
-}
-
-/*
- * Initialize a user-supplied lnode.
- */
-
-CP_HIDDEN lnode_t *lnode_init(lnode_t *lnode, void *data)
-{
- lnode->data = data;
- lnode->next = NULL;
- lnode->prev = NULL;
- return lnode;
-}
-
-/*
- * Destroy a dynamically allocated node.
- */
-
-CP_HIDDEN void lnode_destroy(lnode_t *lnode)
-{
- assert (!lnode_is_in_a_list(lnode));
- free(lnode);
-}
-
-/*
- * Initialize a node pool object to use a user-supplied set of nodes.
- * The ``nodes'' pointer refers to an array of lnode_t objects, containing
- * ``n'' elements.
- */
-
-CP_HIDDEN lnodepool_t *lnode_pool_init(lnodepool_t *pool, lnode_t *nodes, listcount_t n)
-{
- listcount_t i;
-
- assert (n != 0);
-
- pool->pool = nodes;
- pool->fre = nodes;
- pool->size = n;
- for (i = 0; i < n - 1; i++) {
- nodes[i].next = nodes + i + 1;
- }
- nodes[i].next = NULL;
- nodes[i].prev = nodes; /* to make sure node is marked ``on list'' */
- return pool;
-}
-
-/*
- * Create a dynamically allocated pool of n nodes.
- */
-
-CP_HIDDEN lnodepool_t *lnode_pool_create(listcount_t n)
-{
- lnodepool_t *pool;
- lnode_t *nodes;
-
- assert (n != 0);
-
- pool = malloc(sizeof *pool);
- if (!pool)
- return NULL;
- nodes = malloc(n * sizeof *nodes);
- if (!nodes) {
- free(pool);
- return NULL;
- }
- lnode_pool_init(pool, nodes, n);
- return pool;
-}
-
-/*
- * Determine whether the given pool is from this pool.
- */
-
-CP_HIDDEN int lnode_pool_isfrom(lnodepool_t *pool, lnode_t *node)
-{
- listcount_t i;
-
- /* this is carefully coded this way because ANSI C forbids pointers
- to different objects from being subtracted or compared other
- than for exact equality */
-
- for (i = 0; i < pool->size; i++) {
- if (pool->pool + i == node)
- return 1;
- }
- return 0;
-}
-
-/*
- * Destroy a dynamically allocated pool of nodes.
- */
-
-CP_HIDDEN void lnode_pool_destroy(lnodepool_t *p)
-{
- free(p->pool);
- free(p);
-}
-
-/*
- * Borrow a node from a node pool. Returns a null pointer if the pool
- * is exhausted.
- */
-
-CP_HIDDEN lnode_t *lnode_borrow(lnodepool_t *pool, void *data)
-{
- lnode_t *new = pool->fre;
- if (new) {
- pool->fre = new->next;
- new->data = data;
- new->next = NULL;
- new->prev = NULL;
- }
- return new;
-}
-
-/*
- * Return a node to a node pool. A node must be returned to the pool
- * from which it came.
- */
-
-CP_HIDDEN void lnode_return(lnodepool_t *pool, lnode_t *node)
-{
- assert (lnode_pool_isfrom(pool, node));
- assert (!lnode_is_in_a_list(node));
-
- node->next = pool->fre;
- node->prev = node;
- pool->fre = node;
-}
-
-/*
- * Determine whether the given list contains the given node.
- * According to this function, a list does not contain its nilnode.
- */
-
-CP_HIDDEN int list_contains(list_t *list, lnode_t *node)
-{
- lnode_t *n, *nil = list_nil(list);
-
- for (n = list_first_priv(list); n != nil; n = lnode_next(n)) {
- if (node == n)
- return 1;
- }
-
- return 0;
-}
-
-/*
- * A more generalized variant of list_transfer. This one removes a
- * ``slice'' from the source list and appends it to the destination
- * list.
- */
-
-CP_HIDDEN void list_extract(list_t *dest, list_t *source, lnode_t *first, lnode_t *last)
-{
- listcount_t moved = 1;
-
- assert (first == NULL || list_contains(source, first));
- assert (last == NULL || list_contains(source, last));
-
- if (first == NULL || last == NULL)
- return;
-
- /* adjust the destination list so that the slice is spliced out */
-
- first->prev->next = last->next;
- last->next->prev = first->prev;
-
- /* graft the splice at the end of the dest list */
-
- last->next = &dest->nilnode;
- first->prev = dest->nilnode.prev;
- dest->nilnode.prev->next = first;
- dest->nilnode.prev = last;
-
- while (first != last) {
- first = first->next;
- assert (first != list_nil(source)); /* oops, last before first! */
- moved++;
- }
-
- /* assert no overflows */
- assert (source->nodecount - moved <= source->nodecount);
- assert (dest->nodecount + moved >= dest->nodecount);
-
- /* assert no weirdness */
- assert (moved <= source->nodecount);
-
- source->nodecount -= moved;
- dest->nodecount += moved;
-
- /* assert list sanity */
- assert (list_verify(source));
- assert (list_verify(dest));
-}
-
-
-/*
- * Split off a trailing sequence of nodes from the source list and relocate
- * them to the tail of the destination list. The trailing sequence begins
- * with node ``first'' and terminates with the last node of the source
- * list. The nodes are added to the end of the new list in their original
- * order.
- */
-
-CP_HIDDEN void list_transfer(list_t *dest, list_t *source, lnode_t *first)
-{
- listcount_t moved = 1;
- lnode_t *last;
-
- assert (first == NULL || list_contains(source, first));
-
- if (first == NULL)
- return;
-
- last = source->nilnode.prev;
-
- source->nilnode.prev = first->prev;
- first->prev->next = &source->nilnode;
-
- last->next = &dest->nilnode;
- first->prev = dest->nilnode.prev;
- dest->nilnode.prev->next = first;
- dest->nilnode.prev = last;
-
- while (first != last) {
- first = first->next;
- moved++;
- }
-
- /* assert no overflows */
- assert (source->nodecount - moved <= source->nodecount);
- assert (dest->nodecount + moved >= dest->nodecount);
-
- /* assert no weirdness */
- assert (moved <= source->nodecount);
-
- source->nodecount -= moved;
- dest->nodecount += moved;
-
- /* assert list sanity */
- assert (list_verify(source));
- assert (list_verify(dest));
-}
-
-CP_HIDDEN void list_merge(list_t *dest, list_t *sour,
- int compare (const void *, const void *))
-{
- lnode_t *dn, *sn, *tn;
- lnode_t *d_nil = list_nil(dest), *s_nil = list_nil(sour);
-
- /* Nothing to do if source and destination list are the same. */
- if (dest == sour)
- return;
-
- /* overflow check */
- assert (list_count(sour) + list_count(dest) >= list_count(sour));
-
- /* lists must be sorted */
- assert (list_is_sorted(sour, compare));
- assert (list_is_sorted(dest, compare));
-
- dn = list_first_priv(dest);
- sn = list_first_priv(sour);
-
- while (dn != d_nil && sn != s_nil) {
- if (compare(lnode_get(dn), lnode_get(sn)) >= 0) {
- tn = lnode_next(sn);
- list_delete(sour, sn);
- list_ins_before(dest, sn, dn);
- sn = tn;
- } else {
- dn = lnode_next(dn);
- }
- }
-
- if (dn != d_nil)
- return;
-
- if (sn != s_nil)
- list_transfer(dest, sour, sn);
-}
-
-CP_HIDDEN void list_sort(list_t *list, int compare(const void *, const void *))
-{
- list_t extra;
- listcount_t middle;
- lnode_t *node;
-
- if (list_count(list) > 1) {
- middle = list_count(list) / 2;
- node = list_first_priv(list);
-
- list_init(&extra, list_count(list) - middle);
-
- while (middle--)
- node = lnode_next(node);
-
- list_transfer(&extra, list, node);
- list_sort(list, compare);
- list_sort(&extra, compare);
- list_merge(list, &extra, compare);
- }
- assert (list_is_sorted(list, compare));
-}
-
-CP_HIDDEN lnode_t *list_find(list_t *list, const void *key, int compare(const void *, const void *))
-{
- lnode_t *node;
-
- for (node = list_first_priv(list); node != list_nil(list); node = node->next) {
- if (compare(lnode_get(node), key) == 0)
- return node;
- }
-
- return 0;
-}
-
-
-/*
- * Return 1 if the list is in sorted order, 0 otherwise
- */
-
-CP_HIDDEN int list_is_sorted(list_t *list, int compare(const void *, const void *))
-{
- lnode_t *node, *next, *nil;
-
- next = nil = list_nil(list);
- node = list_first_priv(list);
-
- if (node != nil)
- next = lnode_next(node);
-
- for (; next != nil; node = next, next = lnode_next(next)) {
- if (compare(lnode_get(node), lnode_get(next)) > 0)
- return 0;
- }
-
- return 1;
-}
-
-/*
- * Get rid of macro functions definitions so they don't interfere
- * with the actual definitions
- */
-
-#undef list_isempty
-#undef list_isfull
-#undef lnode_pool_isempty
-#undef list_append
-#undef list_prepend
-#undef list_first
-#undef list_last
-#undef list_next
-#undef list_prev
-#undef list_count
-#undef list_del_first
-#undef list_del_last
-#undef lnode_put
-#undef lnode_get
-
-/*
- * Return 1 if the list is empty, 0 otherwise
- */
-
-CP_HIDDEN int list_isempty(list_t *list)
-{
- return list->nodecount == 0;
-}
-
-/*
- * Return 1 if the list is full, 0 otherwise
- * Permitted only on bounded lists.
- */
-
-CP_HIDDEN int list_isfull(list_t *list)
-{
- return list->nodecount == list->maxcount;
-}
-
-/*
- * Check if the node pool is empty.
- */
-
-CP_HIDDEN int lnode_pool_isempty(lnodepool_t *pool)
-{
- return (pool->fre == NULL);
-}
-
-/*
- * Add the given node at the end of the list
- */
-
-CP_HIDDEN void list_append(list_t *list, lnode_t *node)
-{
- list_ins_before(list, node, &list->nilnode);
-}
-
-/*
- * Add the given node at the beginning of the list.
- */
-
-CP_HIDDEN void list_prepend(list_t *list, lnode_t *node)
-{
- list_ins_after(list, node, &list->nilnode);
-}
-
-/*
- * Retrieve the first node of the list
- */
-
-CP_HIDDEN lnode_t *list_first(list_t *list)
-{
- if (list->nilnode.next == &list->nilnode)
- return NULL;
- return list->nilnode.next;
-}
-
-/*
- * Retrieve the last node of the list
- */
-
-CP_HIDDEN lnode_t *list_last(list_t *list)
-{
- if (list->nilnode.prev == &list->nilnode)
- return NULL;
- return list->nilnode.prev;
-}
-
-/*
- * Retrieve the count of nodes in the list
- */
-
-CP_HIDDEN listcount_t list_count(list_t *list)
-{
- return list->nodecount;
-}
-
-/*
- * Remove the first node from the list and return it.
- */
-
-CP_HIDDEN lnode_t *list_del_first(list_t *list)
-{
- return list_delete(list, list->nilnode.next);
-}
-
-/*
- * Remove the last node from the list and return it.
- */
-
-CP_HIDDEN lnode_t *list_del_last(list_t *list)
-{
- return list_delete(list, list->nilnode.prev);
-}
-
-
-/*
- * Associate a data item with the given node.
- */
-
-CP_HIDDEN void lnode_put(lnode_t *lnode, void *data)
-{
- lnode->data = data;
-}
-
-/*
- * Retrieve the data item associated with the node.
- */
-
-CP_HIDDEN void *lnode_get(lnode_t *lnode)
-{
- return lnode->data;
-}
-
-/*
- * Retrieve the node's successor. If there is no successor,
- * NULL is returned.
- */
-
-CP_HIDDEN lnode_t *list_next(list_t *list, lnode_t *lnode)
-{
- assert (list_contains(list, lnode));
-
- if (lnode->next == list_nil(list))
- return NULL;
- return lnode->next;
-}
-
-/*
- * Retrieve the node's predecessor. See comment for lnode_next().
- */
-
-CP_HIDDEN lnode_t *list_prev(list_t *list, lnode_t *lnode)
-{
- assert (list_contains(list, lnode));
-
- if (lnode->prev == list_nil(list))
- return NULL;
- return lnode->prev;
-}
-
-/*
- * Return 1 if the lnode is in some list, otherwise return 0.
- */
-
-CP_HIDDEN int lnode_is_in_a_list(lnode_t *lnode)
-{
- return (lnode->next != NULL || lnode->prev != NULL);
-}
-
-
-CP_HIDDEN int list_verify(list_t *list)
-{
- lnode_t *node = list_first_priv(list), *nil = list_nil(list);
- listcount_t count = list_count(list);
-
- if (node->prev != nil)
- return 0;
-
- if (count > list->maxcount)
- return 0;
-
- while (node != nil && count--) {
- if (node->next->prev != node)
- return 0;
- node = node->next;
- }
-
- if (count != 0 || node != nil)
- return 0;
-
- return 1;
-}
-
-#ifdef KAZLIB_TEST_MAIN
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-typedef char input_t[256];
-
-static int tokenize(char *string, ...)
-{
- char **tokptr;
- va_list arglist;
- int tokcount = 0;
-
- va_start(arglist, string);
- tokptr = va_arg(arglist, char **);
- while (tokptr) {
- while (*string && isspace((unsigned char) *string))
- string++;
- if (!*string)
- break;
- *tokptr = string;
- while (*string && !isspace((unsigned char) *string))
- string++;
- tokptr = va_arg(arglist, char **);
- tokcount++;
- if (!*string)
- break;
- *string++ = 0;
- }
- va_end(arglist);
-
- return tokcount;
-}
-
-static int comparef(const void *key1, const void *key2)
-{
- return strcmp(key1, key2);
-}
-
-static char *dupstring(char *str)
-{
- int sz = strlen(str) + 1;
- char *new = malloc(sz);
- if (new)
- memcpy(new, str, sz);
- return new;
-}
-
-int main(void)
-{
- input_t in;
- list_t *l = list_create(LISTCOUNT_T_MAX);
- lnode_t *ln;
- char *tok1, *val;
- int prompt = 0;
-
- char *help =
- "a <val> append value to list\n"
- "d <val> delete value from list\n"
- "l <val> lookup value in list\n"
- "s sort list\n"
- "c show number of entries\n"
- "t dump whole list\n"
- "p turn prompt on\n"
- "q quit";
-
- if (!l)
- puts("list_create failed");
-
- for (;;) {
- if (prompt)
- putchar('>');
- fflush(stdout);
-
- if (!fgets(in, sizeof(input_t), stdin))
- break;
-
- switch(in[0]) {
- case '?':
- puts(help);
- break;
- case 'a':
- if (tokenize(in+1, &tok1, (char **) 0) != 1) {
- puts("what?");
- break;
- }
- val = dupstring(tok1);
- ln = lnode_create(val);
-
- if (!val || !ln) {
- puts("allocation failure");
- if (ln)
- lnode_destroy(ln);
- free(val);
- break;
- }
-
- list_append(l, ln);
- break;
- case 'd':
- if (tokenize(in+1, &tok1, (char **) 0) != 1) {
- puts("what?");
- break;
- }
- ln = list_find(l, tok1, comparef);
- if (!ln) {
- puts("list_find failed");
- break;
- }
- list_delete(l, ln);
- val = lnode_get(ln);
- lnode_destroy(ln);
- free(val);
- break;
- case 'l':
- if (tokenize(in+1, &tok1, (char **) 0) != 1) {
- puts("what?");
- break;
- }
- ln = list_find(l, tok1, comparef);
- if (!ln)
- puts("list_find failed");
- else
- puts("found");
- break;
- case 's':
- list_sort(l, comparef);
- break;
- case 'c':
- printf("%lu\n", (unsigned long) list_count(l));
- break;
- case 't':
- for (ln = list_first(l); ln != 0; ln = list_next(l, ln))
- puts(lnode_get(ln));
- break;
- case 'q':
- exit(0);
- break;
- case '\0':
- break;
- case 'p':
- prompt = 1;
- break;
- default:
- putchar('?');
- putchar('\n');
- break;
- }
- }
-
- return 0;
-}
-
-#endif /* defined TEST_MAIN */