/* -*- mode: c ; c-file-style: "canonware-c-style" -*-
 ******************************************************************************
 *
 * Copyright (C) 1996-2004 Jason Evans <jasone@canonware.com>.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice(s), this list of conditions and the following disclaimer
 *    unmodified other than the allowable addition of one or more
 *    copyright notices.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice(s), this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 *
 * Version: Onyx 5.1.1
 *
 ******************************************************************************/

#include "../include/libonyx/libonyx.h"

/* Number of ring entries (<= 26, preferrably). */
#define NENTRIES 8

typedef struct ring_s ring_t;

struct ring_s
{
    qr(ring_t) link;
    char id;
};

int
main()
{
    uint32_t i;
    ring_t entries[NENTRIES], *t;

    libonyx_init(0, NULL, NULL);
    fprintf(stderr, "Test begin\n");

    /* Initialize entries. */
    fprintf(stderr, "qr_new()\n");
    for (i = 0; i < NENTRIES; i++)
    {
	qr_new(&entries[i], link);
	entries[i].id = 'a' + i;
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_next(&entries[i], link);
	fprintf(stderr, "  qr_next(%c): %c\n", entries[i].id, t->id);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_prev(&entries[i], link);
	fprintf(stderr, "  qr_prev(%c): %c\n", entries[i].id, t->id);
    }

    /* Link the entries together. */
    fprintf(stderr, "qr_after_insert()\n");
    for (i = 1; i < NENTRIES; i++)
    {
	qr_after_insert(&entries[i - 1], &entries[i], link);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_next(&entries[i], link);
	fprintf(stderr, "  qr_next(%c): %c\n", entries[i].id, t->id);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_prev(&entries[i], link);
	fprintf(stderr, "  qr_prev(%c): %c\n", entries[i].id, t->id);
    }

    fprintf(stderr, "qr_remove()\n");
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):        ", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
	qr_remove(&entries[i], link);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_next(&entries[i], link);
	fprintf(stderr, "  qr_next(%c): %c\n", entries[i].id, t->id);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_prev(&entries[i], link);
	fprintf(stderr, "  qr_prev(%c): %c\n", entries[i].id, t->id);
    }

    /* Link the entries together. */
    fprintf(stderr, "qr_before_insert()\n");
    for (i = 1; i < NENTRIES; i++)
    {
	qr_before_insert(&entries[i - 1], &entries[i], link);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_next(&entries[i], link);
	fprintf(stderr, "  qr_next(%c): %c\n", entries[i].id, t->id);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_prev(&entries[i], link);
	fprintf(stderr, "  qr_prev(%c): %c\n", entries[i].id, t->id);
    }

    fprintf(stderr, "qr_remove()\n");
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):        ", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	    {
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
	qr_remove(&entries[i], link);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_reverse_foreach(%c):", entries[i].id);
	qr_reverse_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_next(&entries[i], link);
	fprintf(stderr, "  qr_next(%c): %c\n", entries[i].id, t->id);
    }
    for (i = 0; i < NENTRIES; i++)
    {
	t = qr_prev(&entries[i], link);
	fprintf(stderr, "  qr_prev(%c): %c\n", entries[i].id, t->id);
    }

    /* meld, split */
    fprintf(stderr, "qr_split(a, e)\n");
    for (i = 1; i < NENTRIES; i++)
    {
	qr_after_insert(&entries[i - 1], &entries[i], link);
    }
    qr_split(&entries[0], &entries[4], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_meld(a, e)\n");
    qr_meld(&entries[0], &entries[4], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_meld(a, e)\n");
    qr_meld(&entries[0], &entries[4], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_split(a, e)\n");
    qr_split(&entries[0], &entries[4], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_split(a, a)\n");
    qr_split(&entries[0], &entries[0], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_meld(a, a)\n");
    qr_meld(&entries[0], &entries[0], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_split(a, b)\n");
    qr_split(&entries[0], &entries[1], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }
    fprintf(stderr, "qr_meld(a, b)\n");
    qr_meld(&entries[0], &entries[1], ring_t, link);
    for (i = 0; i < NENTRIES; i++)
    {
	fprintf(stderr, "  qr_foreach(%c):", entries[i].id);
	qr_foreach(t, &entries[i], link)
	{
	    fprintf(stderr, " %c", t->id);
	}
	fprintf(stderr, "\n");
    }

    fprintf(stderr, "Test end\n");
    libonyx_shutdown();
    return 0;
}
