#include "c.h"

static char rcsid[] = "$Id: list.nw,v 2.1 1995/07/17 14:31:52 drh Exp $";

static List freenodes;          /* free list nodes */

/* append - append x to list, return new list */
List append(void *x, List list) {
        List new;

        if ((new = freenodes) != NULL)
                freenodes = freenodes->link;
        else
                NEW(new, PERM);
        if (list) {
                new->link = list->link;
                list->link = new;
        } else
                new->link = new;
        new->x = x;
        return new;
}

/* length - # elements in list */
int length(List list) {
        int n = 0;

        if (list) {
                List lp = list;
                do
                        n++;
                while ((lp = lp->link) != list);
        }
        return n;
}

/* ltov - convert list to an NULL-terminated vector allocated in arena */
void *ltov(List *list, unsigned arena) {
        int i = 0;
        void **array = newarray(length(*list) + 1, sizeof array[0], arena);

        if (*list) {
                List lp = *list;
                do {
                        lp = lp->link;
                        array[i++] = lp->x;
                } while (lp != *list);
#ifndef PURIFY
                lp = (*list)->link;
                (*list)->link = freenodes;
                freenodes = lp;
#endif
        }
        *list = NULL;
        array[i] = NULL;
        return array;
}
