/* this is the brisby fancy list */ #ifndef __list_h #define __list_h #include "mem.h" #include "error.h" #include 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