/* 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