/* this is the brisby fancy list */
#ifndef __list_h
#define __list_h

#include "mem.h"
#include "error.h"

#include <stdlib.h>

struct list_s {
	char *str;
	struct list_s *next;
};

typedef struct list_s *list_t;

static int inline list_length(list_t x) {
	int i;
	for (i = 0; x; x = x->next, i++);
	return i;
}
static void inline list_push(list_t *x, char *str) {
	list_t p;

	/* never push empty stuff on */
	if (str == 0)
		return;

	p = mem_alloc(sizeof(list_t));
	if (!p)
		cfatal("mem_alloc: %s");
	p->next = (*x);
	p->str = str;
	*x = p;
}
static char inline *list_pop(list_t *x) {
	list_t p;
	char *q;

	p = (*x);
	if (p) {
		*x = p->next;
		q = p->str;
		mem_free(p);
	} else
		q = 0;
	return q;
}
static void inline list_reverse(list_t *p) {
	list_t x = 0;
	char *q;

	if (!p || !*p)
		return;
	while ((q = list_pop(p))) {
		list_push(&x, q);
	}
	*p = x;
}
static char inline *__list_randomize_helper(list_t *x) 
{
	char *q;
	list_t p;
	if (!x || !*x || !(*x)->next) return 0;
	q = (*x)->next->str;
	p = (*x)->next;
	(*x)->next = (*x)->next->next;
	mem_free(p);
	return q;
}
static void inline list_randomize(list_t *p) {
	list_t x = 0, y;
	int i, j, k, q, z;
	char *s;

	/* no need */
	if (!p || !*p || !(*p)->next)
		return;
	if (!(*p)->next->next) {
		/* shortcut */
		if (rand() % 2 == 0) {
			list_reverse(p);
		}
		return;
	}
	/* count list elements */
	for (i = 0, x = *p; x; i++, x = x->next);

	/* x is 0 again */
	j = i;
	for (z = j*j; z > 0; z--) {
		i = j; while (i > 2 && *p) {
			k = rand() % (i+1);
			for (y = *p, q = 0; q < k; q++, y = y->next);
			if (!y) {
				i--;
				list_push(&x, list_pop(p));
				continue;
			}
			s = __list_randomize_helper(&y);
			if (!s) continue;
			list_push(&x, s);
			i--;
		}
		while (*p) {
			list_push(&x, list_pop(p));
		}
	}
	*p = x;
}

#endif


syntax highlighted by Code2HTML, v. 0.9.1