diff options
author | Andrew Shadura <andrew@shadura.me> | 2014-01-28 15:21:50 +0100 |
---|---|---|
committer | Andrew Shadura <andrew@shadura.me> | 2014-01-28 15:21:50 +0100 |
commit | 51addbcf27d7b06dae80a0e39e5f5f83e94dd8ae (patch) | |
tree | 3d00bef2d26f97257ec6f4835505cd300054a1e3 /src/libmowgli/base | |
parent | 1ed00f1a2893b43195f3fc747988da0bf6006797 (diff) |
Update to libmowgli 2.0.0
Diffstat (limited to 'src/libmowgli/base')
-rw-r--r-- | src/libmowgli/base/Makefile | 29 | ||||
-rw-r--r-- | src/libmowgli/base/argstack.c | 247 | ||||
-rw-r--r-- | src/libmowgli/base/argstack.h | 57 | ||||
-rw-r--r-- | src/libmowgli/base/bitvector.c | 238 | ||||
-rw-r--r-- | src/libmowgli/base/bitvector.h | 41 | ||||
-rw-r--r-- | src/libmowgli/base/formatter.c | 119 | ||||
-rw-r--r-- | src/libmowgli/base/formatter.h | 31 | ||||
-rw-r--r-- | src/libmowgli/base/hash.c | 74 | ||||
-rw-r--r-- | src/libmowgli/base/hash.h | 30 | ||||
-rw-r--r-- | src/libmowgli/base/hook.c | 146 | ||||
-rw-r--r-- | src/libmowgli/base/hook.h | 47 | ||||
-rw-r--r-- | src/libmowgli/base/memslice.c | 146 | ||||
-rw-r--r-- | src/libmowgli/base/memslice.h | 27 | ||||
-rw-r--r-- | src/libmowgli/base/mowgli_signal.c | 66 | ||||
-rw-r--r-- | src/libmowgli/base/mowgli_signal.h | 31 | ||||
-rw-r--r-- | src/libmowgli/base/random.c | 143 | ||||
-rw-r--r-- | src/libmowgli/base/random.h | 45 |
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 |