summaryrefslogtreecommitdiff
path: root/src/libmowgli/base
diff options
context:
space:
mode:
authorAndrew Shadura <andrew@shadura.me>2014-01-28 15:21:50 +0100
committerAndrew Shadura <andrew@shadura.me>2014-01-28 15:21:50 +0100
commit51addbcf27d7b06dae80a0e39e5f5f83e94dd8ae (patch)
tree3d00bef2d26f97257ec6f4835505cd300054a1e3 /src/libmowgli/base
parent1ed00f1a2893b43195f3fc747988da0bf6006797 (diff)
Update to libmowgli 2.0.0
Diffstat (limited to 'src/libmowgli/base')
-rw-r--r--src/libmowgli/base/Makefile29
-rw-r--r--src/libmowgli/base/argstack.c247
-rw-r--r--src/libmowgli/base/argstack.h57
-rw-r--r--src/libmowgli/base/bitvector.c238
-rw-r--r--src/libmowgli/base/bitvector.h41
-rw-r--r--src/libmowgli/base/formatter.c119
-rw-r--r--src/libmowgli/base/formatter.h31
-rw-r--r--src/libmowgli/base/hash.c74
-rw-r--r--src/libmowgli/base/hash.h30
-rw-r--r--src/libmowgli/base/hook.c146
-rw-r--r--src/libmowgli/base/hook.h47
-rw-r--r--src/libmowgli/base/memslice.c146
-rw-r--r--src/libmowgli/base/memslice.h27
-rw-r--r--src/libmowgli/base/mowgli_signal.c66
-rw-r--r--src/libmowgli/base/mowgli_signal.h31
-rw-r--r--src/libmowgli/base/random.c143
-rw-r--r--src/libmowgli/base/random.h45
17 files changed, 1517 insertions, 0 deletions
diff --git a/src/libmowgli/base/Makefile b/src/libmowgli/base/Makefile
new file mode 100644
index 0000000..3d6b0e7
--- /dev/null
+++ b/src/libmowgli/base/Makefile
@@ -0,0 +1,29 @@
+include ../../../extra.mk
+
+STATIC_PIC_LIB_NOINST = ${LIBMOWGLI_SHARED_BASE}
+STATIC_LIB_NOINST = ${LIBMOWGLI_STATIC_BASE}
+
+SRCS = argstack.c \
+ bitvector.c \
+ formatter.c \
+ hash.c \
+ hook.c \
+ memslice.c \
+ random.c \
+ mowgli_signal.c
+
+INCLUDES = argstack.h \
+ bitvector.h \
+ formatter.h \
+ hash.h \
+ hook.h \
+ memslice.h \
+ random.h \
+ mowgli_signal.h
+
+include ../../../buildsys.mk
+
+includesubdir = $(PACKAGE_NAME)/base
+
+CPPFLAGS += -I. -I.. -I../../.. -DMOWGLI_CORE
+
diff --git a/src/libmowgli/base/argstack.c b/src/libmowgli/base/argstack.c
new file mode 100644
index 0000000..ea67da2
--- /dev/null
+++ b/src/libmowgli/base/argstack.c
@@ -0,0 +1,247 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * argstack.c: Argument stacks.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+static mowgli_object_class_t klass;
+
+/*
+ * \brief Private destructor for the mowgli_argstack_t object.
+ *
+ * \param vptr pointer to mowgli_argstack_t to destroy.
+ */
+static void mowgli_argstack_destroy(void *vptr)
+{
+ mowgli_argstack_t *self = (mowgli_argstack_t *) vptr;
+ mowgli_node_t *n, *tn;
+
+ MOWGLI_LIST_FOREACH_SAFE(n, tn, self->stack.head)
+ {
+ mowgli_free(n->data);
+
+ mowgli_node_delete(n, &self->stack);
+ mowgli_node_free(n);
+ }
+
+ mowgli_free(self);
+}
+
+/*
+ * \brief Initialization code for the mowgli.argstack library.
+ *
+ * Side Effects:
+ * - the mowgli_argstack_t object class is registered.
+ */
+void mowgli_argstack_bootstrap(void)
+{
+ mowgli_object_class_init(&klass, "mowgli_argstack_t", mowgli_argstack_destroy, FALSE);
+}
+
+/*
+ * \brief Creates an argument stack from a va_list and an appropriate
+ * description schema.
+ *
+ * \param descstr a description string which describes the argument stack, where:
+ * + the character 's' means that the value for that slot is a string
+ * + the character 'd' means that the value for that slot is a numeric
+ * + the character 'p' means that the value for that slot is a generic pointer
+ * + the character 'b' means that the value for that slot is a boolean
+ * \param va a va_list containing data to populate the argument stack with.
+ *
+ * \return a mowgli_argstack_t (mowgli.argstack) object.
+ */
+mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_list va)
+{
+ const char *cp = descstr;
+ mowgli_argstack_t *out = mowgli_alloc(sizeof(mowgli_argstack_t));
+ mowgli_object_init(mowgli_object(out), descstr, &klass, NULL);
+
+ if (descstr == NULL)
+ mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
+
+ while (*cp)
+ {
+ mowgli_argstack_element_t *e = mowgli_alloc(sizeof(mowgli_argstack_element_t));
+
+ switch(*cp)
+ {
+ case 's':
+ e->data.string = va_arg(va, char *);
+ e->type = MOWGLI_ARG_STRING;
+ break;
+ case 'd':
+ e->data.numeric = va_arg(va, int);
+ e->type = MOWGLI_ARG_NUMERIC;
+ break;
+ case 'p':
+ e->data.pointer = va_arg(va, void *);
+ e->type = MOWGLI_ARG_POINTER;
+ break;
+ case 'b':
+ e->data.boolean = va_arg(va, mowgli_boolean_t);
+ e->type = MOWGLI_ARG_BOOLEAN;
+ break;
+ default:
+ va_end(va);
+ mowgli_object_unref(out);
+ mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
+ break;
+ }
+
+ mowgli_node_add(e, mowgli_node_create(), &out->stack);
+ cp++;
+ }
+
+ return out;
+}
+
+/*
+ * \brief Creates an argument stack.
+ *
+ * \param descstr a description string which describes the argument stack, where:
+ * + the character 's' means that the value for that slot is a string
+ * + the character 'd' means that the value for that slot is a numeric
+ * + the character 'p' means that the value for that slot is a generic pointer
+ * + the character 'b' means that the value for that slot is a boolean
+ * \param va a va_list containing data to populate the argument stack with.
+ *
+ * \return a mowgli_argstack_t (mowgli.argstack) object.
+ */
+mowgli_argstack_t *mowgli_argstack_create(const char *descstr, ...)
+{
+ va_list va;
+ mowgli_argstack_t *out;
+
+ if (descstr == NULL)
+ mowgli_throw_exception_val(mowgli.argstack.invalid_description, NULL);
+
+ va_start(va, descstr);
+ out = mowgli_argstack_create_from_va_list(descstr, va);
+ va_end(va);
+
+ return out;
+}
+
+/*
+ * \brief Convenience function to pop a string value off of an argument stack.
+ *
+ * \param self A mowgli_argstack_t object to pop a string off of.
+ *
+ * \return On success, a string.
+ *
+ * Side Effects:
+ * - the argument is removed from the argstack.
+ */
+const char *mowgli_argstack_pop_string(mowgli_argstack_t *self)
+{
+ mowgli_node_t *n;
+ mowgli_argstack_element_t *e;
+
+ if (self == NULL)
+ mowgli_throw_exception_val(mowgli.null_pointer_exception, NULL);
+
+ n = self->stack.head;
+ mowgli_node_delete(n, &self->stack);
+ e = n->data;
+ mowgli_node_free(n);
+
+ return e->data.string;
+}
+
+/*
+ * \brief Convenience function to pop a numeric value off of an argument stack.
+ *
+ * \param self A mowgli_argstack_t object to pop a numeric off of.
+ *
+ * \return On success, a numeric.
+ *
+ * Side Effects:
+ * - the argument is removed from the argstack.
+ */
+int mowgli_argstack_pop_numeric(mowgli_argstack_t *self)
+{
+ mowgli_node_t *n;
+ mowgli_argstack_element_t *e;
+
+ if (self == NULL)
+ mowgli_throw_exception_val(mowgli.null_pointer_exception, 0);
+
+ n = self->stack.head;
+ mowgli_node_delete(n, &self->stack);
+ e = n->data;
+ mowgli_node_free(n);
+
+ return e->data.numeric;
+}
+
+/*
+ * Convenience function to pop a boolean value off of an argument stack.
+ *
+ * \param self A mowgli_argstack_t object to pop a boolean off of.
+ *
+ * \return On success, a boolean value.
+ *
+ * Side Effects:
+ * - the argument is removed from the argstack.
+ */
+mowgli_boolean_t mowgli_argstack_pop_boolean(mowgli_argstack_t *self)
+{
+ mowgli_node_t *n;
+ mowgli_argstack_element_t *e;
+
+ if (self == NULL)
+ mowgli_throw_exception_val(mowgli.null_pointer_exception, FALSE);
+
+ n = self->stack.head;
+ mowgli_node_delete(n, &self->stack);
+ e = n->data;
+ mowgli_node_free(n);
+
+ return e->data.boolean;
+}
+
+/*
+ * \brief Convenience function to pop a pointer value off of an argument stack.
+ *
+ * \param self A mowgli_argstack_t object to pop a pointer off of.
+ *
+ * \return On success, a pointer.
+ *
+ * Side Effects:
+ * - the argument is removed from the argstack.
+ */
+void *mowgli_argstack_pop_pointer(mowgli_argstack_t *self)
+{
+ mowgli_node_t *n;
+ mowgli_argstack_element_t *e;
+
+ if (self == NULL)
+ mowgli_throw_exception_val(mowgli.null_pointer_exception, NULL);
+
+ n = self->stack.head;
+ mowgli_node_delete(n, &self->stack);
+ e = n->data;
+ mowgli_node_free(n);
+
+ return e->data.pointer;
+}
diff --git a/src/libmowgli/base/argstack.h b/src/libmowgli/base/argstack.h
new file mode 100644
index 0000000..adf68c2
--- /dev/null
+++ b/src/libmowgli/base/argstack.h
@@ -0,0 +1,57 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * argstack.h: Argument stacks.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_ARGSTACK_H__
+#define __MOWGLI_ARGSTACK_H__
+
+typedef enum {
+ MOWGLI_ARG_NUMERIC,
+ MOWGLI_ARG_POINTER,
+ MOWGLI_ARG_STRING,
+ MOWGLI_ARG_BOOLEAN
+} mowgli_argstack_element_type_t;
+
+typedef struct {
+ union {
+ int numeric;
+ void *pointer;
+ char *string;
+ mowgli_boolean_t boolean;
+ } data;
+ mowgli_argstack_element_type_t type;
+} mowgli_argstack_element_t;
+
+typedef struct {
+ mowgli_object_t parent;
+ mowgli_list_t stack;
+} mowgli_argstack_t;
+
+extern void mowgli_argstack_bootstrap(void);
+extern mowgli_argstack_t *mowgli_argstack_create(const char *descstr, ...);
+extern mowgli_argstack_t *mowgli_argstack_create_from_va_list(const char *descstr, va_list va);
+extern const char *mowgli_argstack_pop_string(mowgli_argstack_t *);
+extern int mowgli_argstack_pop_numeric(mowgli_argstack_t *);
+extern mowgli_boolean_t mowgli_argstack_pop_boolean(mowgli_argstack_t *);
+extern void *mowgli_argstack_pop_pointer(mowgli_argstack_t *);
+
+#endif
diff --git a/src/libmowgli/base/bitvector.c b/src/libmowgli/base/bitvector.c
new file mode 100644
index 0000000..b70df55
--- /dev/null
+++ b/src/libmowgli/base/bitvector.c
@@ -0,0 +1,238 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * bitvector.c: Bitvectors.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+static mowgli_object_class_t klass;
+
+/*
+ * mowgli_bitvector_init(void)
+ *
+ * Initialization code for the mowgli.bitvector library.
+ *
+ * Inputs:
+ * - none
+ *
+ * Outputs:
+ * - none
+ *
+ * Side Effects:
+ * - the mowgli_bitvector_t object class is registered.
+ */
+void mowgli_bitvector_bootstrap(void)
+{
+ mowgli_object_class_init(&klass, "mowgli_bitvector_t", mowgli_free, FALSE);
+}
+
+/*
+ * mowgli_bitvector_create(int bits)
+ *
+ * Creates a bitvector.
+ *
+ * Inputs:
+ * - amount of bits that the bitvector should store
+ *
+ * Outputs:
+ * - a mowgli.bitvector object
+ *
+ * Side Effects:
+ * - none
+ */
+mowgli_bitvector_t *mowgli_bitvector_create(int bits)
+{
+ mowgli_bitvector_t *bv = (mowgli_bitvector_t *) mowgli_alloc(sizeof(mowgli_bitvector_t));
+ mowgli_object_init(mowgli_object(bv), "mowgli_bitvector_t", &klass, NULL);
+
+ bv->bits = bits;
+ bv->divisor = sizeof(int);
+ bv->vector = (unsigned int *) mowgli_alloc_array(bv->divisor, bv->bits / bv->divisor);
+
+ return bv;
+}
+
+/*
+ * mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val)
+ *
+ * Sets a bit either ON or OFF in the bitvector.
+ *
+ * Inputs:
+ * - a mowgli bitvector object
+ * - a slot
+ * - the value for that slot
+ *
+ * Outputs:
+ * - nothing
+ *
+ * Side Effects:
+ * - a bit is either set ON or OFF in the bitvector.
+ */
+void mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val)
+{
+ int value = 1 << slot;
+
+ switch(val)
+ {
+ case FALSE:
+ bv->vector[bv->bits / bv->divisor] &= ~value;
+ break;
+ default:
+ case TRUE:
+ bv->vector[bv->bits / bv->divisor] |= value;
+ break;
+ }
+}
+
+/*
+ * mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot)
+ *
+ * Returns whether the bit in a given slot is ON or OFF.
+ *
+ * Inputs:
+ * - a mowgli.bitvector object
+ * - a slot to lookup
+ *
+ * Outputs:
+ * - TRUE if the bit is on
+ * - FALSE otherwise
+ *
+ * Side Effects:
+ * - none
+ */
+mowgli_boolean_t mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot)
+{
+ int mask = 1 << slot;
+
+ return ((bv->vector[bv->bits / bv->divisor] & mask) != 0) ? TRUE : FALSE;
+}
+
+/*
+ * mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+ *
+ * Combines two bitvectors together.
+ *
+ * Inputs:
+ * - two bitvectors to be combined
+ *
+ * Outputs:
+ * - a new bitvector containing the combined result.
+ *
+ * Side Effects:
+ * - none
+ */
+mowgli_bitvector_t *mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+{
+ int bits, iter, bs;
+ mowgli_bitvector_t *out;
+
+ return_val_if_fail(bv1 != NULL, NULL);
+ return_val_if_fail(bv2 != NULL, NULL);
+
+ /* choose the larger bitwidth */
+ bits = bv1->bits > bv2->bits ? bv1->bits : bv2->bits;
+
+ /* create the third bitvector. */
+ out = mowgli_bitvector_create(bits);
+
+ /* cache the size of the bitvector in memory. */
+ bs = out->bits / out->divisor;
+
+ for (iter = 0; iter < bs; iter++)
+ {
+ out->vector[iter] |= bv1->vector[iter];
+ out->vector[iter] |= bv2->vector[iter];
+ }
+
+ return out;
+}
+
+/*
+ * mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+ *
+ * XORs two bitvectors together.
+ *
+ * Inputs:
+ * - two bitvectors to be XORed
+ *
+ * Outputs:
+ * - a new bitvector containing the XORed result.
+ *
+ * Side Effects:
+ * - none
+ */
+mowgli_bitvector_t *mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+{
+ int bits, iter, bs;
+ mowgli_bitvector_t *out;
+
+ return_val_if_fail(bv1 != NULL, NULL);
+ return_val_if_fail(bv2 != NULL, NULL);
+
+ /* choose the larger bitwidth */
+ bits = bv1->bits > bv2->bits ? bv1->bits : bv2->bits;
+
+ /* create the third bitvector. */
+ out = mowgli_bitvector_create(bits);
+
+ /* cache the size of the bitvector in memory. */
+ bs = out->bits / out->divisor;
+
+ for (iter = 0; iter < bs; iter++)
+ {
+ out->vector[iter] = bv1->vector[iter];
+ out->vector[iter] &= ~bv2->vector[iter];
+ }
+
+ return out;
+}
+
+/*
+ * mowgli_bitvector_compare(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+ *
+ * Compares two bitvectors to each other.
+ *
+ * Inputs:
+ * - two bitvectors to be compared
+ *
+ * Outputs:
+ * - TRUE if the bitvector is equal
+ * - FALSE otherwise
+ *
+ * Side Effects:
+ * - none
+ */
+mowgli_boolean_t mowgli_bitvector_compare(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2)
+{
+ int iter, bs;
+ mowgli_boolean_t ret = TRUE;
+
+ /* cache the size of the bitvector in memory. */
+ bs = bv1->bits / bv1->divisor;
+
+ for (iter = 0; iter < bs; iter++)
+ {
+ if (!(bv1->vector[iter] & bv2->vector[iter]))
+ ret = FALSE;
+ }
+
+ return ret;
+}
diff --git a/src/libmowgli/base/bitvector.h b/src/libmowgli/base/bitvector.h
new file mode 100644
index 0000000..592ba59
--- /dev/null
+++ b/src/libmowgli/base/bitvector.h
@@ -0,0 +1,41 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * bitvector.h: Bitvectors.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_BITVECTOR_H__
+#define __MOWGLI_BITVECTOR_H__
+
+typedef struct {
+ unsigned int bits;
+ unsigned int divisor;
+ unsigned int *vector;
+} mowgli_bitvector_t;
+
+extern void mowgli_bitvector_bootstrap(void);
+extern mowgli_bitvector_t *mowgli_bitvector_create(int bits);
+extern void mowgli_bitvector_set(mowgli_bitvector_t *bv, int slot, mowgli_boolean_t val);
+extern mowgli_boolean_t mowgli_bitvector_get(mowgli_bitvector_t *bv, int slot);
+extern mowgli_bitvector_t *mowgli_bitvector_combine(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2);
+extern mowgli_bitvector_t *mowgli_bitvector_xor(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2);
+extern mowgli_boolean_t mowgli_bitvector_compare(mowgli_bitvector_t *bv1, mowgli_bitvector_t *bv2);
+
+#endif
diff --git a/src/libmowgli/base/formatter.c b/src/libmowgli/base/formatter.c
new file mode 100644
index 0000000..21d9e46
--- /dev/null
+++ b/src/libmowgli/base/formatter.c
@@ -0,0 +1,119 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * formatter.c: Reusable formatting.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, mowgli_argstack_t *stack)
+{
+ size_t pos = 0;
+ char *i = buf;
+ const char *fiter = fmtstr;
+
+ return_if_fail(buf != NULL);
+ return_if_fail(fmtstr != NULL);
+ return_if_fail(descstr != NULL);
+
+ *i = '\0';
+
+ while (*fiter && pos <= bufstr)
+ {
+ int arg;
+ mowgli_argstack_element_t *e;
+
+ pos = strlen(buf);
+
+ switch(*fiter)
+ {
+ case '%':
+ fiter++;
+ arg = atoi(fiter);
+ e = mowgli_node_nth_data(&stack->stack, arg - 1);
+
+ while (isdigit(*fiter)) fiter++;
+
+ if (e == NULL)
+ {
+ arg = snprintf(i, bufstr - (i - buf), "(unknown)");
+ i += arg;
+ continue;
+ }
+
+ switch(e->type)
+ {
+ case MOWGLI_ARG_STRING:
+ arg = snprintf(i, bufstr - (i - buf), "%s", e->data.string);
+ i += arg;
+ break;
+ case MOWGLI_ARG_NUMERIC:
+ arg = snprintf(i, bufstr - (i - buf), "%d", e->data.numeric);
+ i += arg;
+ break;
+ case MOWGLI_ARG_POINTER:
+ arg = snprintf(i, bufstr - (i - buf), "%p", e->data.pointer);
+ i += arg;
+ break;
+ case MOWGLI_ARG_BOOLEAN:
+ arg = snprintf(i, bufstr - (i - buf), "%s", e->data.boolean ? "TRUE" : "FALSE");
+ i += arg;
+ break;
+ default:
+ mowgli_throw_exception(mowgli.formatter.unhandled_type_exception);
+ break;
+ }
+
+ continue;
+ break;
+ default:
+ *i = *fiter;
+ }
+
+ i++;
+ fiter++;
+ }
+}
+
+void mowgli_formatter_format(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, ...)
+{
+ va_list va;
+ mowgli_argstack_t *stack;
+
+ va_start(va, descstr);
+ stack = mowgli_argstack_create_from_va_list(descstr, va);
+ va_end(va);
+
+ mowgli_formatter_format_from_argstack(buf, bufstr, fmtstr, descstr, stack);
+}
+
+void mowgli_formatter_print(const char *fmtstr, const char *descstr, ...)
+{
+ va_list va;
+ char buf[65535];
+ mowgli_argstack_t *stack;
+
+ va_start(va, descstr);
+ stack = mowgli_argstack_create_from_va_list(descstr, va);
+ va_end(va);
+
+ mowgli_formatter_format_from_argstack(buf, 65535, fmtstr, descstr, stack);
+ printf("%s", buf);
+}
diff --git a/src/libmowgli/base/formatter.h b/src/libmowgli/base/formatter.h
new file mode 100644
index 0000000..2cfa1ce
--- /dev/null
+++ b/src/libmowgli/base/formatter.h
@@ -0,0 +1,31 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * formatter.h: Reusable formatting.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_FORMATTER_H__
+#define __MOWGLI_FORMATTER_H__
+
+extern void mowgli_formatter_format(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, ...);
+extern void mowgli_formatter_print(const char *fmtstr, const char *descstr, ...);
+extern void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, mowgli_argstack_t *stack);
+
+#endif
diff --git a/src/libmowgli/base/hash.c b/src/libmowgli/base/hash.c
new file mode 100644
index 0000000..7d70d8c
--- /dev/null
+++ b/src/libmowgli/base/hash.c
@@ -0,0 +1,74 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * hash.c: FNV-1 hashing implementation.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+#define HASHINIT 0x811c9dc5
+#define HASHBITS 16
+#define HASHSIZE (1 << HASHBITS) /* 2^16 = 65536 */
+
+int mowgli_fnv_hash_string(const char *p)
+{
+ static int htoast = 0;
+ unsigned int hval = HASHINIT;
+
+ if (htoast == 0)
+ {
+ mowgli_random_t *r = mowgli_random_create();
+ htoast = mowgli_random_int(r);
+ mowgli_object_unref(r);
+ }
+
+ if (!p)
+ return (0);
+ for (; *p != '\0'; ++p)
+ {
+ hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
+ hval ^= (tolower(*p) ^ htoast);
+ }
+
+ return ((hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE);
+}
+
+int mowgli_fnv_hash(unsigned int *p)
+{
+ static int htoast = 0;
+ unsigned int hval = HASHINIT;
+
+ if (htoast == 0)
+ {
+ mowgli_random_t *r = mowgli_random_create();
+ htoast = mowgli_random_int(r);
+ mowgli_object_unref(r);
+ }
+
+ if (!p)
+ return (0);
+ for (; *p != '\0'; ++p)
+ {
+ hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
+ hval ^= (tolower(*p) ^ htoast);
+ }
+
+ return ((hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE);
+}
diff --git a/src/libmowgli/base/hash.h b/src/libmowgli/base/hash.h
new file mode 100644
index 0000000..1848174
--- /dev/null
+++ b/src/libmowgli/base/hash.h
@@ -0,0 +1,30 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * hash.h: FNV-1 hashing implementation.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_HASH_H__
+#define __MOWGLI_HASH_H__
+
+extern int mowgli_fnv_hash_string(const char *data);
+extern int mowgli_fnv_hash(unsigned int *data);
+
+#endif
diff --git a/src/libmowgli/base/hook.c b/src/libmowgli/base/hook.c
new file mode 100644
index 0000000..0af9660
--- /dev/null
+++ b/src/libmowgli/base/hook.c
@@ -0,0 +1,146 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * hook.c: Hooks.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ * Copyright (c) 2007 Giacomo Lozito <james -at- develia.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+static mowgli_patricia_t *mowgli_hooks = NULL;
+static mowgli_heap_t *mowgli_hook_item_heap;
+
+static void _hook_key_canon(char *str)
+{
+ while (*str)
+ {
+ *str = toupper(*str);
+ str++;
+ }
+}
+
+void
+mowgli_hook_bootstrap(void)
+{
+ mowgli_hooks = mowgli_patricia_create(_hook_key_canon);
+ mowgli_hook_item_heap = mowgli_heap_create(sizeof(mowgli_hook_item_t), 64, BH_NOW);
+}
+
+static mowgli_hook_t *
+mowgli_hook_find(const char *name)
+{
+ return mowgli_patricia_retrieve(mowgli_hooks, name);
+}
+
+void
+mowgli_hook_register(const char *name)
+{
+ mowgli_hook_t *hook;
+
+ return_if_fail(name != NULL);
+ return_if_fail((hook = mowgli_hook_find(name)) == NULL);
+
+ hook = mowgli_alloc(sizeof(mowgli_hook_t));
+ hook->name = mowgli_strdup(name);
+
+ mowgli_patricia_add(mowgli_hooks, hook->name, hook);
+}
+
+int
+mowgli_hook_associate(const char *name, mowgli_hook_function_t func, void *user_data)
+{
+ mowgli_hook_t *hook;
+ mowgli_hook_item_t *hookitem;
+
+ return_val_if_fail(name != NULL, -1);
+ return_val_if_fail(func != NULL, -1);
+
+ hook = mowgli_hook_find(name);
+
+ if (hook == NULL)
+ {
+ mowgli_hook_register(name);
+ hook = mowgli_hook_find(name);
+ }
+
+ /* this *cant* happen */
+ return_val_if_fail(hook != NULL, -1);
+
+ hookitem = mowgli_heap_alloc(mowgli_hook_item_heap);
+ hookitem->func = func;
+ hookitem->user_data = user_data;
+
+ mowgli_node_add(hookitem, &hookitem->node, &hook->items);
+
+ return 0;
+}
+
+int
+mowgli_hook_dissociate(const char *name, mowgli_hook_function_t func)
+{
+ mowgli_hook_t *hook;
+ mowgli_node_t *n, *tn;
+
+ return_val_if_fail(name != NULL, -1);
+ return_val_if_fail(func != NULL, -1);
+
+ hook = mowgli_hook_find(name);
+
+ if (hook == NULL)
+ return -1;
+
+ MOWGLI_LIST_FOREACH_SAFE(n, tn, hook->items.head)
+ {
+ mowgli_hook_item_t *hookitem = n->data;
+
+ if (hookitem->func == func)
+ {
+ mowgli_node_delete(&hookitem->node, &hook->items);
+ mowgli_heap_free(mowgli_hook_item_heap, hookitem);
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void
+mowgli_hook_call(const char *name, void *hook_data)
+{
+ mowgli_hook_t *hook;
+ mowgli_node_t *n;
+
+ return_if_fail(name != NULL);
+
+ hook = mowgli_hook_find(name);
+
+ if (hook == NULL)
+ return;
+
+ MOWGLI_LIST_FOREACH(n, hook->items.head)
+ {
+ mowgli_hook_item_t *hookitem = n->data;
+
+ return_if_fail(hookitem->func != NULL);
+
+ hookitem->func(hook_data, hookitem->user_data);
+ }
+}
diff --git a/src/libmowgli/base/hook.h b/src/libmowgli/base/hook.h
new file mode 100644
index 0000000..366e123
--- /dev/null
+++ b/src/libmowgli/base/hook.h
@@ -0,0 +1,47 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * hook.h: Hooks.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ * Copyright (c) 2007 Giacomo Lozito <james -at- develia.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_HOOK_H__
+#define __MOWGLI_HOOK_H__
+
+typedef void (*mowgli_hook_function_t)(void *hook_data, void *user_data);
+
+typedef struct {
+ mowgli_hook_function_t func;
+ void *user_data;
+ mowgli_node_t node;
+} mowgli_hook_item_t;
+
+typedef struct {
+ const char *name;
+ mowgli_list_t items;
+} mowgli_hook_t;
+
+extern void mowgli_hook_bootstrap(void);
+extern void mowgli_hook_register(const char *name);
+extern int mowgli_hook_associate(const char *name, mowgli_hook_function_t func, void * user_data);
+extern int mowgli_hook_dissociate(const char *name, mowgli_hook_function_t func);
+extern void mowgli_hook_call(const char *name, void * hook_data);
+
+#endif
diff --git a/src/libmowgli/base/memslice.c b/src/libmowgli/base/memslice.c
new file mode 100644
index 0000000..a271821
--- /dev/null
+++ b/src/libmowgli/base/memslice.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+static mowgli_list_t allocator_list;
+static mowgli_heap_t *allocator_heap;
+
+/*
+ * Our slice allocation engine.
+ */
+typedef struct {
+ size_t size;
+
+ mowgli_heap_t *heap;
+ mowgli_node_t node;
+} slice_alloc_t;
+
+/*
+ * Allocation tag.
+ */
+typedef struct {
+ slice_alloc_t *owner;
+} slice_tag_t;
+
+/*
+ * Given a size_t, determine the closest power-of-two, which is larger.
+ */
+static inline size_t
+nexthigher(size_t k)
+{
+ size_t i;
+
+ k--;
+ for (i = 1; i < sizeof(k) * 8; i <<= 1)
+ k |= k >> i;
+
+ return k + 1;
+}
+
+/*
+ * Set up an allocator.
+ */
+static inline slice_alloc_t *
+create_allocator(size_t k)
+{
+ slice_alloc_t *a;
+
+ a = mowgli_heap_alloc(allocator_heap);
+ mowgli_node_add(a, &a->node, &allocator_list);
+
+ a->size = k;
+ a->heap = mowgli_heap_create(k, 16, BH_LAZY);
+
+ return a;
+}
+
+/*
+ * Find an allocator which fits the requested allocation size.
+ */
+static inline slice_alloc_t *
+find_or_create_allocator(size_t i)
+{
+ size_t k;
+ mowgli_node_t *n;
+
+ k = nexthigher(i);
+ MOWGLI_ITER_FOREACH(n, allocator_list.head)
+ {
+ slice_alloc_t *a = n->data;
+
+ if (a->size == k)
+ return a;
+ }
+
+ return create_allocator(k);
+}
+
+/*
+ * Allocate a slice of memory.
+ */
+static void *
+memslice_alloc(size_t i)
+{
+ void *ptr;
+ slice_alloc_t *alloc;
+ size_t adj_size;
+
+ adj_size = i + sizeof(slice_tag_t);
+ alloc = find_or_create_allocator(adj_size);
+
+ ptr = mowgli_heap_alloc(alloc->heap);
+ ((slice_tag_t *) ptr)->owner = alloc;
+
+ return ptr + sizeof(slice_tag_t);
+}
+
+/*
+ * Free a slice of memory.
+ */
+static void
+memslice_free(void *ptr)
+{
+ slice_tag_t *tag;
+
+ return_if_fail(ptr != NULL);
+
+ tag = ptr - sizeof(slice_tag_t);
+ mowgli_heap_free(tag->owner->heap, tag);
+}
+
+/*
+ * Initialize memslice.
+ */
+static mowgli_allocation_policy_t *memslice = NULL;
+
+void
+mowgli_memslice_bootstrap(void)
+{
+ allocator_heap = mowgli_heap_create(sizeof(slice_alloc_t), 16, BH_NOW);
+
+ memslice = mowgli_allocation_policy_create("memslice", memslice_alloc, memslice_free);
+}
+
+mowgli_allocation_policy_t *
+mowgli_memslice_get_policy(void)
+{
+ return memslice;
+}
diff --git a/src/libmowgli/base/memslice.h b/src/libmowgli/base/memslice.h
new file mode 100644
index 0000000..9d6e842
--- /dev/null
+++ b/src/libmowgli/base/memslice.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_MEMSLICE_H__
+#define __MOWGLI_MEMSLICE_H__
+
+void mowgli_memslice_bootstrap(void);
+mowgli_allocation_policy_t *mowgli_memslice_get_policy(void);
+
+#endif
diff --git a/src/libmowgli/base/mowgli_signal.c b/src/libmowgli/base/mowgli_signal.c
new file mode 100644
index 0000000..208ce37
--- /dev/null
+++ b/src/libmowgli/base/mowgli_signal.c
@@ -0,0 +1,66 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * mowgli_signal.c: Safe signal handling.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef _WIN32
+
+#include <signal.h>
+#include "mowgli.h"
+
+static mowgli_signal_handler_t
+mowgli_signal_install_handler_full(int signum, mowgli_signal_handler_t handler,
+ int *sigtoblock, size_t sigtoblocksize)
+{
+ struct sigaction action, old_action;
+ size_t i;
+
+ action.sa_handler = handler;
+ action.sa_flags = SA_RESTART;
+
+ sigemptyset(&action.sa_mask);
+
+ for (i = 0; i < sigtoblocksize; i++)
+ sigaddset(&action.sa_mask, sigtoblock[i]);
+
+ if (sigaction(signum, &action, &old_action) == -1)
+ {
+ mowgli_log("Failed to install signal handler for signal %d", signum);
+ return NULL;
+ }
+
+ return old_action.sa_handler;
+}
+
+/*
+ * A version of signal(2) that works more reliably across different
+ * platforms.
+ *
+ * It restarts interrupted system calls, does not reset the handler,
+ * and blocks the same signal from within the handler.
+ */
+mowgli_signal_handler_t
+mowgli_signal_install_handler(int signum, mowgli_signal_handler_t handler)
+{
+ return mowgli_signal_install_handler_full(signum, handler, NULL, 0);
+}
+
+#endif
diff --git a/src/libmowgli/base/mowgli_signal.h b/src/libmowgli/base/mowgli_signal.h
new file mode 100644
index 0000000..b194d8d
--- /dev/null
+++ b/src/libmowgli/base/mowgli_signal.h
@@ -0,0 +1,31 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * mowgli_signal.h: Safe signal handling.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_SIGNAL_H__
+#define __MOWGLI_SIGNAL_H__
+
+typedef void (*mowgli_signal_handler_t) (int);
+
+extern mowgli_signal_handler_t mowgli_signal_install_handler(int signum, mowgli_signal_handler_t handler);
+
+#endif
diff --git a/src/libmowgli/base/random.c b/src/libmowgli/base/random.c
new file mode 100644
index 0000000..b316033
--- /dev/null
+++ b/src/libmowgli/base/random.c
@@ -0,0 +1,143 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * random.c: Portable mersinne-twister based psuedo-random number generator.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ * Algorithm copyright (c) 1999-2007 Takuji Nishimura and Makoto Matsumoto
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "mowgli.h"
+
+/* period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+/* mowgli_random_t contains state data which is private */
+struct mowgli_random_
+{
+ mowgli_object_t object;
+ unsigned int mt[N];
+ size_t mti;
+};
+
+static mowgli_object_class_t klass;
+
+/* initialization */
+void mowgli_random_bootstrap(void)
+{
+ mowgli_object_class_init(&klass, "mowgli_random_t", NULL, FALSE);
+}
+
+/* construction and destruction. */
+mowgli_random_t *mowgli_random_create(void)
+{
+ return mowgli_random_create_with_seed(time(NULL));
+}
+
+mowgli_random_t *mowgli_random_create_with_seed(unsigned int seed)
+{
+ mowgli_random_t *out = mowgli_alloc(sizeof(mowgli_random_t));
+ mowgli_object_init(mowgli_object(out), NULL, &klass, NULL);
+
+ mowgli_random_reseed(out, seed);
+
+ return out;
+}
+
+/* reset seed */
+void mowgli_random_reseed(mowgli_random_t *self, unsigned int seed)
+{
+ return_if_fail(self != NULL);
+
+ self->mt[0] = seed & 0xffffffffUL;
+ for (self->mti = 1; self->mti < N; self->mti++)
+ {
+ self->mt[self->mti] = (1812433253UL * (self->mt[self->mti - 1] ^ (self->mt[self->mti - 1] >> 30)) + self->mti);
+ self->mt[self->mti] &= 0xffffffffUL;
+ }
+}
+
+/* number retrieval */
+unsigned int mowgli_random_int(mowgli_random_t *self)
+{
+ unsigned int y;
+ static unsigned int mag01[2] = { 0x0UL, MATRIX_A };
+
+ return_val_if_fail(self != NULL, 0);
+
+ if (self->mti >= N)
+ {
+ int t;
+
+ for (t = 0; t < N - M; t++)
+ {
+ y = (self->mt[t] & UPPER_MASK) | (self->mt[t + 1] & LOWER_MASK);
+ self->mt[t] = self->mt[t + M] ^ (y >> 1) ^ mag01[y & 0x1U];
+ }
+
+ for (; t < N - 1; t++)
+ {
+ y = (self->mt[t] & UPPER_MASK) | (self->mt[t + 1] & LOWER_MASK);
+ self->mt[t] = self->mt[t + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U];
+ }
+
+ y = (self->mt[N - 1] & UPPER_MASK) | (self->mt[0] & LOWER_MASK);
+ self->mt[N - 1] = self->mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1U];
+ self->mti = 0;
+ }
+
+ y = self->mt[self->mti++];
+
+ /* tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680U;
+ y ^= (y << 15) & 0xefc60000U;
+ y ^= (y >> 18);
+
+ return y;
+}
+
+int mowgli_random_int_ranged(mowgli_random_t *self, int begin, int end)
+{
+ unsigned int dist = end - begin;
+ unsigned int max, ret;
+
+ if (dist <= 0x80000000U)
+ {
+ unsigned int remain = (0x80000000U % dist) * 2;
+
+ if (remain >= dist)
+ remain -= dist;
+
+ max = 0xFFFFFFFFU - remain;
+ } else
+ max = dist - 1;
+
+ do
+ {
+ ret = mowgli_random_int(self);
+ } while (ret > max);
+
+ ret %= dist;
+
+ return begin + ret;
+}
diff --git a/src/libmowgli/base/random.h b/src/libmowgli/base/random.h
new file mode 100644
index 0000000..ea53dd7
--- /dev/null
+++ b/src/libmowgli/base/random.h
@@ -0,0 +1,45 @@
+/*
+ * libmowgli: A collection of useful routines for programming.
+ * random.h: Portable mersinne-twister based psuedo-random number generator.
+ *
+ * Copyright (c) 2007 William Pitcock <nenolod -at- sacredspiral.co.uk>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice is present in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#ifndef __MOWGLI_RANDOM_H__
+#define __MOWGLI_RANDOM_H__
+
+/* mowgli_random_t contains state data which is private */
+struct mowgli_random_;
+typedef struct mowgli_random_ mowgli_random_t;
+
+/* object class initialization. */
+extern void mowgli_random_bootstrap(void);
+
+/* construction and destruction. */
+extern mowgli_random_t *mowgli_random_create(void);
+extern mowgli_random_t *mowgli_random_create_with_seed(unsigned int seed);
+
+/* reset seed */
+extern void mowgli_random_reseed(mowgli_random_t *self, unsigned int seed);
+
+/* number retrieval */
+extern unsigned int mowgli_random_int(mowgli_random_t *self);
+extern int mowgli_random_int_ranged(mowgli_random_t *self, int begin, int end);
+
+#endif