changeset 381:7c28f38cb6dd

Update to use new th-libs from the subrepo.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 03 Oct 2011 15:43:42 +0300
parents 727ce827482b
children 2c9630c765fa
files .hgsubstate Makefile.gen nnchat.c th_args.c th_args.h th_config.c th_config.h th_string.c th_string.h th_types.h th_util.c th_util.h
diffstat 12 files changed, 9 insertions(+), 2741 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgsubstate	Mon Oct 03 15:43:42 2011 +0300
@@ -0,0 +1,1 @@
+598609fb49b06e34f96230f464fef400bafeb2d8 th-libs
--- a/Makefile.gen	Mon Oct 03 15:43:01 2011 +0300
+++ b/Makefile.gen	Mon Oct 03 15:43:42 2011 +0300
@@ -23,11 +23,14 @@
 #
 all: $(NONBUILD) $(TARGETS)
 
-$(OBJPATH)%.o: %.c %.h
+$(OBJPATH)%.o: th-libs/%.c th-libs/%.h
 	$(CC) $(CFLAGS) -c -o $@ $<
 
+$(OBJPATH)%.o: %.c %.h
+	$(CC) $(CFLAGS) -c -o $@ $< -Ith-libs/
+
 $(NNCHAT_BIN): nnchat.c $(OBJPATH)libnnchat.o $(OBJPATH)th_util.o $(OBJPATH)th_string.o $(OBJPATH)th_args.o $(OBJPATH)th_config.o $(EXTRAOBJS) VERSION
-	$(CC) $(CFLAGS) -o $@ $(filter %.c %.o,$+) $(LDFLAGS) -DNN_VERSION=\"$(NN_VERSION)\"
+	$(CC) $(CFLAGS) -o $@ $(filter %.c %.o,$+) $(LDFLAGS) -DNN_VERSION=\"$(NN_VERSION)\" -Ith-libs/
 
 #
 # Special targets
--- a/nnchat.c	Mon Oct 03 15:43:01 2011 +0300
+++ b/nnchat.c	Mon Oct 03 15:43:42 2011 +0300
@@ -105,8 +105,10 @@
 
 void argShowHelp(void)
 {
-    th_args_help(stdout, optList, optListN, th_prog_name,
+    th_print_banner(stdout, th_prog_name,
         "[options] <username> <password>");
+    
+    th_args_help(stdout, optList, optListN);
 }
 
 
--- a/th_args.c	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,431 +0,0 @@
-/*
- * Simple commandline argument processing
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-/*
-Description
-===========
-Structures and functions for simple commandline argument processing,
-option argument handling (short and long forms supported).
-
-Output function for printing out short on-line help for said options
-and program commandline usage.
-
-
-Format for typical commandline:
-
-$ program -a -b -c --long-d -e argument-for-e --long-f="argument for f"
-
-where -a, -b and -c are short options without required arguments;
---long-d is a long option without argument; -e is short option with
-argument and finally --long-f is long option with argument.
-
-
-Introduction
-============
-Handling of commandline options in th_args_process() has various
-options, which effect how an option is handled. Also the error
-situations (unknown option/no required argument) can be handled
-in different ways.
-
-Typically th_args_process() is called as follows:
-
-BOOL optionHandlerCallback(int optionNumber, char *optionArgument, char *optionName)
-{
-  if (option is OK)
-    return TRUE;
-  else
-    return FALSE;
-}
-
-BOOL nonoptionHandlerCallback(char *argumentString)
-{
-  // return value same as in optionHandlerCallback
-}
-
-
-int main(int argc, char *argv[])
-{
-  if (th_args_process(argc, argv, optList, optListN,
-      optionHandlerCallback, nonoptionHandlerCallback)) {
-    ... arguments OK ...
-  } else {
-    ... arguments invalid or required arguments missing ...
-  }
-}
-
-
-NOTICE!
--------
-The return value from handler callbacks affects the return value of
-th_args_process(). Additionally, a failure in callback (returns FALSE)
-effects the argument processing if bailOut argument of th_args_process()
-is TRUE!
-
-If bailOut is TRUE, any error/failure in argument processing (including
-callbacks) immediately stops the argument processing and FALSE is
-returned from th_args_process().
-
-If bailOut is FALSE, most errors are "ignored", but FALSE is still returned
-if any errors occured.
-
-
-NOTICE #2!
-----------
-A small temporary buffer of N*sizeof(BOOL) (where N is number of
-options in optList[]) is allocated for processing required options.
-If this allocation fails, the program is immediately exited with
-code 128.
-
-
-Examples
-========
-Example of different options, in a fictional optionlist struct:
-
-optarg_t optList[] = {
-  // Option without arguments
-  { 0, '?', "help",      "Show this help",                    OPT_NONE },
-
-  // Option with a required argument
-  { 1, 'o', "output",    "Output file name",                  OPT_ARGREQ },
-  
-  // Option with optional argument
-  { 2, 'f', "foobar",    "Use foobar, with optional string",  OPT_ARGOPT },
-
-  // This option is required to be given, though without other flags
-  // it may not make much sense.
-  { 4, 'S', "stupid",     "You must give this option",        OPT_REQUIRED },
-
-  // The flags can be combined with OR operator: this option is both
-  // required to be specified, and also requires argument (the filename)
-  { 5, 'i', "input",     "Input file name",                   OPT_REQUIRED | OPT_ARGREQ },
-
-
-  // Option with only long form
-  { 0, 0,   "only-long", "Long option",                       OPT_NONE },
-
-  // Option with only short form
-  { 0, 's', NULL,        "Short option",                      OPT_NONE },
-
-};
-
-const int optListN = (sizeof(optList) / sizeof(optarg_t));
-
-
-*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "th_util.h"
-#include "th_args.h"
-#include "th_string.h"
-
-
-/* Check if option requires an argument
- */
-static BOOL th_args_check_arg(optarg_t *o, char *optArg)
-{
-    if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL)
-    {
-        if (o->optShort != 0 && o->optLong != NULL)
-        {
-            THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n",
-                  o->optShort, o->optLong);
-        }
-        else if (o->optShort != 0)
-        {
-            THERR("Option '-%c ARG' requires an argument!\n", o->optShort);
-        }
-        else if (o->optLong != NULL)
-        {
-            THERR("Option --%s=ARG requires an argument!\n", o->optLong);
-        }
-
-        return FALSE;
-    }
-    else
-        return TRUE;
-}
-
-
-/* Handle short options
- */
-static BOOL th_args_process_short(char *currArg, int *newArgIndex,
-                                  BOOL *wasGiven, int argc, char *argv[],
-                                  optarg_t optList[], int optListN,
-                                  BOOL(*handleOpt) (int, char *, char *))
-{
-    char *tmpArg = currArg, *optArg;
-    int optN;
-    BOOL isFound;
-
-    /* Short options can be combined: -a -b -c == -abc */
-    while (*tmpArg)
-    {
-        for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++)
-            if (*tmpArg == optList[optN].optShort)
-            {
-                /* Get possible option argument, if needed */
-                if ((optList[optN].optFlags & OPT_ARGMASK) != 0
-                    && (++(*newArgIndex) < argc))
-                    optArg = argv[*newArgIndex];
-                else
-                    optArg = NULL;
-
-                /* Check if option argument is required */
-                if (!th_args_check_arg(&optList[optN], optArg))
-                    return FALSE;
-                else
-                {
-                    char tmpStr[2] = { 0, 0 };
-
-                    /* Option was given succesfully, try to handle it */
-                    wasGiven[optN] = TRUE;
-
-                    tmpStr[0] = *tmpArg;
-
-                    if (!handleOpt(optList[optN].optID, optArg, tmpStr))
-                        return FALSE;
-                }
-
-                isFound = TRUE;
-            }
-
-        if (!isFound)
-        {
-            THERR("Unknown short option '%c' in argument '-%s'\n",
-                  *tmpArg, currArg);
-            return FALSE;
-        }
-
-        tmpArg++;
-    }
-
-    return TRUE;
-}
-
-
-/* Handle long options
- */
-static BOOL th_args_process_long(char *currArg, int *newArgIndex,
-                                 BOOL *wasGiven, int argc, char *argv[],
-                                 optarg_t optList[], int optListN,
-                                 BOOL(*handleOpt) (int, char *, char *))
-{
-    int optN, optLen, i;
-    char *optArg;
-
-    (void) argc;
-    (void) argv;
-    (void) newArgIndex;
-
-    /* Long option */
-    for (optN = -1, optLen = i = 0; (i < optListN) && (optN < 0); i++)
-        if (optList[i].optLong)
-        {
-            optLen = strlen(optList[i].optLong);
-            if (strncmp(currArg, optList[i].optLong, optLen) == 0)
-                optN = i;
-        }
-
-    /* Get possible option argument, if needed */
-    if (optN >= 0)
-    {
-        if ((optList[optN].optFlags & OPT_ARGMASK) != 0)
-        {
-            if (currArg[optLen] == '=')
-                optArg = &currArg[optLen + 1];
-            else
-                optArg = NULL;
-        }
-        else
-            optArg = NULL;
-
-        /* Check if option argument is required */
-        if (!th_args_check_arg(&optList[optN], optArg))
-            return FALSE;
-        else
-        {
-            /* Option was given succesfully, try to handle it */
-            wasGiven[optN] = TRUE;
-            if (!handleOpt(optList[optN].optID, optArg, currArg))
-                return FALSE;
-        }
-    }
-    else
-    {
-        THERR("Unknown long option '--%s'\n", currArg);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-
-/* Process arguments, handling short and long options by
- * calling the given callback functions.
- */
-BOOL th_args_process(int argc, char *argv[],
-                     optarg_t optList[], int optListN,
-                     BOOL(*handleOpt) (int, char *, char *),
-                     BOOL(*handleNonOption) (char *), BOOL bailOut)
-{
-    BOOL endOptions, optionsOK;
-    int argIndex, newArgIndex, i;
-    char *currArg;
-    BOOL *wasGiven;
-
-    /* Allocate wasGiven */
-    wasGiven = (BOOL *) th_calloc(optListN, sizeof(BOOL));
-    if (!wasGiven)
-    {
-        THERR
-            ("FATAL ERROR! Could not allocate wasGiven in th_args_process()!\n");
-        exit(128);
-    }
-
-    /* Parse arguments */
-    argIndex = 1;
-    optionsOK = TRUE;
-    endOptions = FALSE;
-    while (argIndex < argc)
-    {
-        currArg = argv[argIndex];
-        if ((currArg[0] == '-') && !endOptions)
-        {
-            newArgIndex = argIndex;
-            currArg++;
-            if (*currArg == '-')
-            {
-                /* Check for "--", which ends the options-list */
-                currArg++;
-                if (*currArg == 0)
-                {
-                    endOptions = TRUE;
-                    continue;
-                }
-
-                /* Long options */
-                if (!th_args_process_long(currArg, &newArgIndex,
-                                          wasGiven, argc, argv, optList,
-                                          optListN, handleOpt))
-                    optionsOK = FALSE;
-            }
-            else
-            {
-                /* Short options */
-                if (!th_args_process_short(currArg, &newArgIndex,
-                                           wasGiven, argc, argv, optList,
-                                           optListN, handleOpt))
-                    optionsOK = FALSE;
-            }
-
-            argIndex = newArgIndex;
-        }
-        else
-        {
-            /* Was not option argument */
-            if (handleNonOption == NULL
-                || (handleNonOption != NULL && !handleNonOption(currArg)))
-            {
-                THERR("Invalid argument '%s'\n", currArg);
-                optionsOK = FALSE;
-            }
-        }
-
-        /* Check if we bail out on invalid argument */
-        if (!optionsOK && bailOut)
-        {
-            th_free(wasGiven);
-            return FALSE;
-        }
-
-        argIndex++;
-    }
-
-    /* Check wasGiven by isRequired */
-    for (i = 0; i < optListN; i++)
-        if ((optList[i].optFlags & OPT_REQUIRED) != 0 && !wasGiven[i])
-        {
-            THERR("Option -%s (--%s) is required.\n",
-                  optList[i].optShort, optList[i].optLong);
-
-            optionsOK = FALSE;
-            if (bailOut)
-                break;
-        }
-
-    th_free(wasGiven);
-    return optionsOK;
-}
-
-
-/* Print help for commandline arguments/options
- */
-void th_args_help(FILE *outFile,
-                  optarg_t optList[], int optListN,
-                  char *progName, char *progUsage)
-{
-    int i, nrequired;
-
-    fprintf(outFile,
-            "\n%s v%s (%s)\n"
-            "%s\n"
-            "%s\n"
-            "Usage: %s %s\n",
-            th_prog_name, th_prog_version, th_prog_fullname,
-            th_prog_author, th_prog_license, progName, progUsage);
-
-
-    for (i = nrequired = 0; i < optListN; i++)
-    {
-        optarg_t *o = &optList[i];
-
-        /* Print short option */
-        if (o->optShort != 0)
-            fprintf(outFile, "  -%c,  ", o->optShort);
-        else
-            fprintf(outFile, "       ");
-
-        /* Print long option */
-        if (o->optLong)
-        {
-            char tmpStr[64], *p;
-
-            if ((o->optFlags & OPT_ARGMASK) == OPT_ARGOPT)
-            {
-                snprintf(tmpStr, sizeof(tmpStr), "%s[=ARG]",
-                         optList[i].optLong);
-                p = tmpStr;
-            }
-            else if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ)
-            {
-                snprintf(tmpStr, sizeof(tmpStr), "%s=ARG",
-                         optList[i].optLong);
-                p = tmpStr;
-            }
-            else
-                p = o->optLong;
-
-            fprintf(outFile, "--%-15s", p);
-        }
-        else
-            fprintf(outFile, "                 ");
-
-        fprintf(outFile, "  %s.", optList[i].optDesc);
-
-        if (o->optFlags & OPT_REQUIRED)
-        {
-            fprintf(outFile, " [*]\n");
-            nrequired++;
-        }
-        else
-            fprintf(outFile, "\n");
-    }
-
-    if (nrequired > 0)
-        fprintf(outFile, "(Options marked with [*] are required)\n");
-}
--- a/th_args.h	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Simple commandline argument processing function
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifndef _TH_ARGS
-#define _TH_ARGS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include "th_util.h"
-
-
-/* Option flags
- */
-#define OPT_NONE       (0)    /* Simple option with no arguments */
-#define OPT_ARGREQ     (1)    /* Option's argument is required */
-#define OPT_ARGOPT     (3)    /* Option's argument is optional */
-#define OPT_ARGMASK    (3)    /* Mask for option argument flags */
-#define OPT_REQUIRED   (4)    /* This option is required to be given */
-
-
-typedef struct {
-    int optID;
-    char optShort;
-    char *optLong;
-    char *optDesc;
-    int optFlags;
-} optarg_t;
-
-
-BOOL th_args_process(int argc, char *argv[],
-     optarg_t argList[], int argListN,
-     BOOL (*handleOpt)(int, char *, char *),
-     BOOL (*handleFile)(char *), BOOL);
-
-void th_args_help(FILE *, optarg_t optList[], int optListN, char *, char *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _TH_ARGS */
--- a/th_config.c	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,847 +0,0 @@
-/*
- * Very simple configuration handling functions
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2004-2010 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <stdio.h>
-#include <stdarg.h>
-#include "th_config.h"
-#include "th_util.h"
-#include "th_string.h"
-
-#define SET_MAX_BUF     (8192)
-
-
-/* Free a given configuration (the values are not free'd)
- */
-void th_cfg_free(cfgitem_t *cfg)
-{
-    cfgitem_t *curr = cfg;
-
-    while (curr != NULL)
-    {
-        cfgitem_t *next = curr->next;
-
-        if (curr->type == ITEM_SECTION)
-            th_cfg_free((cfgitem_t *) curr->v.data);
-
-        th_free(curr->name);
-        th_free(curr);
-        curr = next;
-    }
-}
-
-
-/* Allocate and add new item to configuration
- */
-static cfgitem_t *th_cfg_add(cfgitem_t **cfg, const char *name,
-                             const int type, void *data)
-{
-    cfgitem_t *node;
-
-    if (cfg == NULL)
-        return NULL;
-
-    /* Allocate new item */
-    node = (cfgitem_t *) th_calloc(1, sizeof(cfgitem_t));
-    if (node == NULL)
-        return NULL;
-
-    /* Set values */
-    node->type = type;
-    node->v.data = data;
-    node->name = th_strdup(name);
-
-    /* Insert into linked list */
-    if (*cfg != NULL)
-    {
-        node->prev = (*cfg)->prev;
-        (*cfg)->prev->next = node;
-        (*cfg)->prev = node;
-    }
-    else
-    {
-        *cfg = node;
-        node->prev = node;
-    }
-    node->next = NULL;
-
-    return node;
-}
-
-
-/* Add integer type setting into give configuration
- */
-int th_cfg_add_int(cfgitem_t **cfg, char *name, int *itemData, int itemDef)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_INT, (void *) itemData);
-    if (node == NULL)
-        return -1;
-
-    *itemData = itemDef;
-
-    return 0;
-}
-
-
-int th_cfg_add_hexvalue(cfgitem_t **cfg, char *name,
-                        int *itemData, int itemDef)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_HEX_TRIPLET, (void *) itemData);
-    if (node == NULL)
-        return -1;
-
-    *itemData = itemDef;
-
-    return 0;
-}
-
-
-/* Add unsigned integer type setting into give configuration
- */
-int th_cfg_add_uint(cfgitem_t **cfg, char *name,
-                    unsigned int *itemData, unsigned int itemDef)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_UINT, (void *) itemData);
-    if (node == NULL)
-        return -1;
-
-    *itemData = itemDef;
-
-    return 0;
-}
-
-
-/* Add strint type setting into given configuration
- */
-int th_cfg_add_string(cfgitem_t **cfg, char *name,
-                      char **itemData, char *itemDef)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_STRING, (void *) itemData);
-    if (node == NULL)
-        return -1;
-
-    *itemData = th_strdup(itemDef);
-
-    return 0;
-}
-
-
-/* Add boolean type setting into given configuration
- */
-int th_cfg_add_bool(cfgitem_t **cfg, char *name,
-                    BOOL *itemData, BOOL itemDef)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_BOOL, (void *) itemData);
-    if (node == NULL)
-        return -1;
-
-    *itemData = itemDef;
-
-    return 0;
-}
-
-
-/* Add implicit comment
- */
-int th_cfg_add_comment(cfgitem_t **cfg, char *comment)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, comment, ITEM_COMMENT, NULL);
-    if (node == NULL)
-        return -1;
-
-    return 0;
-}
-
-
-/* Add new section
- */
-int th_cfg_add_section(cfgitem_t **cfg, char *name, cfgitem_t *data)
-{
-    cfgitem_t *node;
-
-    node = th_cfg_add(cfg, name, ITEM_SECTION, (void *) data);
-    if (node == NULL)
-        return -1;
-
-    return 0;
-}
-
-
-int th_cfg_add_string_list(cfgitem_t **cfg, char *name, qlist_t **data)
-{
-    cfgitem_t *node;
-
-    if (data == NULL)
-        return -5;
-
-    node = th_cfg_add(cfg, name, ITEM_STRING_LIST, (void *) data);
-    if (node == NULL)
-        return -1;
-
-    return 0;
-}
-
-
-/* Read a given file into configuration structure and variables
- */
-enum
-{
-    PM_EOF,
-    PM_ERROR,
-    PM_NORMAL,
-    PM_COMMENT,
-    PM_NEXT,
-    PM_KEYNAME,
-    PM_KEYSET,
-    PM_STRING,
-    PM_INT,
-    PM_BOOL,
-    PM_SECTION,
-    PM_ARRAY
-};
-
-#define VADDCH(ch) if (strPos < SET_MAX_BUF) { tmpStr[strPos++] = ch; }
-#define VISEND(ch) (ch == '\r' || ch == '\n' || ch == ';' || th_isspace(c) || ch == '#')
-
-typedef struct
-{
-    FILE *file;
-    char *filename;
-    size_t line;
-} conffile_t;
-
-
-static void th_cfg_error(conffile_t *f, const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    fprintf(stderr, "%s: '%s', line #%d: ", th_prog_name, f->filename,
-            (unsigned int) f->line);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-}
-
-
-static int th_cfg_read_sect(conffile_t *f, cfgitem_t *cfg, int nesting)
-{
-    cfgitem_t *item = NULL;
-    char tmpStr[SET_MAX_BUF + 1];
-    size_t strPos;
-    int c, parseMode, prevMode, nextMode, tmpCh;
-    BOOL isFound, isStart, isError, validError;
-
-    /* Initialize values */
-    tmpCh = 0;
-    strPos = 0;
-    c = -1;
-    isFound = isStart = isError = validError = FALSE;
-    nextMode = prevMode = parseMode = PM_NORMAL;
-
-    /* Parse the configuration */
-    while (parseMode != PM_EOF && parseMode != PM_ERROR)
-    {
-        if (c == -1)
-        {
-            /* Get next character */
-            switch (c = fgetc(f->file))
-            {
-            case EOF:
-                if (parseMode != PM_NORMAL)
-                {
-                    th_cfg_error(f, "Unexpected end of file.\n");
-                    parseMode = PM_ERROR;
-                }
-                else
-                    parseMode = PM_EOF;
-                break;
-
-            case '\n':
-                f->line++;
-            }
-        }
-
-        switch (parseMode)
-        {
-        case PM_COMMENT:
-            /* Comment parsing mode */
-            if (c == '\n')
-            {
-                /* End of line, end of comment */
-                parseMode = prevMode;
-                prevMode = PM_COMMENT;
-            }
-            c = -1;
-            break;
-
-        case PM_NORMAL:
-            /* Normal parsing mode */
-            if (c == '#')
-            {
-                prevMode = parseMode;
-                parseMode = PM_COMMENT;
-                c = -1;
-            }
-            else if (VISEND(c))
-            {
-                c = -1;
-            }
-            else if (c == '}')
-            {
-                if (nesting > 0)
-                {
-                    /* Check for validation errors */
-                    return (validError) ? 1 : 0;
-                }
-                else
-                {
-                    th_cfg_error(f,
-                                 "Invalid nesting sequence encountered.\n");
-                    parseMode = PM_ERROR;
-                }
-            }
-            else if (th_isalpha(c))
-            {
-                /* Start of key name found */
-                prevMode = parseMode;
-                parseMode = PM_KEYNAME;
-                strPos = 0;
-            }
-            else
-            {
-                /* Error! Invalid character found */
-                th_cfg_error(f, "Unexpected character '%c'.\n", c);
-                parseMode = PM_ERROR;
-            }
-            break;
-
-        case PM_KEYNAME:
-            /* Configuration KEY name parsing mode */
-            if (c == '#')
-            {
-                /* Start of comment */
-                prevMode = parseMode;
-                parseMode = PM_COMMENT;
-                c = -1;
-            }
-            else if (th_iscrlf(c) || th_isspace(c) || c == '=')
-            {
-                /* End of key name */
-                prevMode = parseMode;
-                parseMode = PM_NEXT;
-                nextMode = PM_KEYSET;
-            }
-            else if (th_isalnum(c) || c == '_')
-            {
-                /* Add to key name string */
-                VADDCH(c)
-                else
-                {
-                    /* Error! Key name string too long! */
-                    th_cfg_error(f, "Config key name too long!");
-                    parseMode = PM_ERROR;
-                }
-                c = -1;
-            }
-            else
-            {
-                /* Error! Invalid character found */
-                tmpStr[strPos] = 0;
-                th_cfg_error(f,
-                             "Unexpected character '%c' in key name '%s'.\n",
-                             c, tmpStr);
-                parseMode = PM_ERROR;
-            }
-            break;
-
-        case PM_KEYSET:
-            if (c == '=')
-            {
-                /* Find key from configuration */
-                tmpStr[strPos] = 0;
-                isFound = FALSE;
-                item = cfg;
-                while (item != NULL && !isFound)
-                {
-                    if (item->name != NULL && strcmp(item->name, tmpStr) == 0)
-                        isFound = TRUE;
-                    else
-                        item = item->next;
-                }
-
-                /* Check if key was found */
-                if (isFound)
-                {
-                    /* Okay, set next mode */
-                    switch (item->type)
-                    {
-                    case ITEM_HEX_TRIPLET:
-                    case ITEM_STRING:
-                        nextMode = PM_STRING;
-                        break;
-
-                    case ITEM_STRING_LIST:
-                        nextMode = PM_ARRAY;
-                        break;
-
-                    case ITEM_INT:
-                    case ITEM_UINT:
-                        nextMode = PM_INT;
-                        break;
-
-                    case ITEM_BOOL:
-                        nextMode = PM_BOOL;
-                        break;
-
-                    case ITEM_SECTION:
-                        nextMode = PM_SECTION;
-                        break;
-                    }
-
-                    prevMode = parseMode;
-                    parseMode = PM_NEXT;
-                    isStart = TRUE;
-                    strPos = 0;
-                }
-                else
-                {
-                    /* Error! No configuration key by this name found */
-                    th_cfg_error(f,
-                                 "No such configuration setting ('%s')\n",
-                                 tmpStr);
-                    parseMode = PM_ERROR;
-                }
-
-                c = -1;
-            }
-            else
-            {
-                /* Error! '=' expected! */
-                th_cfg_error(f,
-                             "Unexpected character '%c', assignation '=' was expected.\n",
-                             c);
-                parseMode = PM_ERROR;
-            }
-            break;
-
-        case PM_NEXT:
-            /* Search next item parsing mode */
-            if (c == '#')
-            {
-                /* Start of comment */
-                prevMode = parseMode;
-                parseMode = PM_COMMENT;
-            }
-            else if (th_isspace(c) || th_iscrlf(c))
-            {
-                /* Ignore whitespaces and linechanges */
-                c = -1;
-            }
-            else
-            {
-                /* Next item found */
-                prevMode = parseMode;
-                parseMode = nextMode;
-            }
-            break;
-
-        case PM_ARRAY:
-            if (isStart)
-            {
-                switch (item->type)
-                {
-                case ITEM_STRING_LIST:
-                    prevMode = parseMode;
-                    parseMode = PM_STRING;
-                    break;
-                }
-            }
-            else if (c == ',')
-            {
-                switch (item->type)
-                {
-                case ITEM_STRING_LIST:
-                    c = -1;
-                    isStart = TRUE;
-                    prevMode = parseMode;
-                    parseMode = PM_NEXT;
-                    nextMode = PM_STRING;
-                    break;
-                }
-            }
-            else
-            {
-                prevMode = parseMode;
-                parseMode = PM_NORMAL;
-            }
-            break;
-
-        case PM_SECTION:
-            /* Section parsing mode */
-            if (c != '{')
-            {
-                /* Error! Section start '{' expected! */
-                th_cfg_error(f,
-                             "Unexpected character '%c', section start '{' was expected.\n",
-                             c);
-                parseMode = PM_ERROR;
-            }
-            else
-            {
-                int res = th_cfg_read_sect(f, item->v.section, nesting + 1);
-                c = -1;
-                if (res > 0)
-                    validError = TRUE;
-                else if (res < 0)
-                    parseMode = PM_ERROR;
-                else
-                {
-                    prevMode = parseMode;
-                    parseMode = PM_NORMAL;
-                }
-            }
-            break;
-
-        case PM_STRING:
-            /* String parsing mode */
-            if (isStart)
-            {
-                /* Start of string, get delimiter */
-                tmpCh = c;
-                isStart = FALSE;
-                strPos = 0;
-            }
-            else if (c == tmpCh)
-            {
-                /* End of string, set the value */
-                tmpStr[strPos] = 0;
-
-                switch (item->type)
-                {
-                case ITEM_HEX_TRIPLET:
-                    *(item->v.val_int) = th_get_hex_triplet(tmpStr);
-                    prevMode = parseMode;
-                    parseMode = PM_NORMAL;
-                    break;
-                case ITEM_STRING:
-                    th_pstrcpy(item->v.val_str, tmpStr);
-                    prevMode = parseMode;
-                    parseMode = PM_NORMAL;
-                    break;
-                case ITEM_STRING_LIST:
-                    th_llist_append(item->v.list, th_strdup(tmpStr));
-                    prevMode = parseMode;
-                    parseMode = PM_NEXT;
-                    nextMode = PM_ARRAY;
-                    break;
-                }
-
-            }
-            else
-            {
-                /* Add character to string */
-                VADDCH(c)
-                else
-                {
-                    /* Error! String too long! */
-                    th_cfg_error(f,
-                                 "String too long! Maximum is %d characters.",
-                                 SET_MAX_BUF);
-                    parseMode = PM_ERROR;
-                }
-            }
-
-            c = -1;
-            break;
-
-        case PM_INT:
-            /* Integer parsing mode */
-            if (isStart && item->type == ITEM_UINT && c == '-')
-            {
-                /* Error! Negative values not allowed for unsigned ints */
-                th_cfg_error(f,
-                             "Negative value specified for %s, unsigned value expected.",
-                             item->name);
-                parseMode = PM_ERROR;
-            }
-            else if (isStart && (c == '-' || c == '+'))
-            {
-                VADDCH(c)
-                else
-                isError = TRUE;
-            }
-            else if (th_isdigit(c))
-            {
-                VADDCH(c)
-                else
-                isError = TRUE;
-            }
-            else if (VISEND(c))
-            {
-                /* End of integer parsing mode */
-                tmpStr[strPos] = 0;
-                switch (item->type)
-                {
-                case ITEM_INT:
-                    *(item->v.val_int) = atoi(tmpStr);
-                    break;
-
-                case ITEM_UINT:
-                    *(item->v.val_uint) = atol(tmpStr);
-                    break;
-                }
-
-                prevMode = parseMode;
-                parseMode = PM_NORMAL;
-            }
-            else
-            {
-                /* Error! Unexpected character. */
-                th_cfg_error(f,
-                             "Unexpected character '%c' for integer setting '%s'.",
-                             c, item->name);
-                parseMode = PM_ERROR;
-            }
-
-            if (isError)
-            {
-                /* Error! String too long! */
-                th_cfg_error(f, "String too long! Maximum is %d characters.",
-                             SET_MAX_BUF);
-                parseMode = PM_ERROR;
-            }
-
-            isStart = FALSE;
-            c = -1;
-            break;
-
-        case PM_BOOL:
-            /* Boolean parsing mode */
-            if (isStart)
-            {
-                tmpCh = c;
-                isStart = FALSE;
-            }
-            else if (VISEND(c))
-            {
-                BOOL tmpBool = FALSE;
-
-                /* End of boolean parsing */
-                switch (tmpCh)
-                {
-                case 'Y':
-                case 'y':
-                case 'T':
-                case 't':
-                case '1':
-                    tmpBool = TRUE;
-                    break;
-
-                case 'N':
-                case 'n':
-                case 'F':
-                case 'f':
-                case '0':
-                    tmpBool = FALSE;
-                    break;
-
-                default:
-                    isError = TRUE;
-                }
-
-                if (isError)
-                {
-                    th_cfg_error(f, "Invalid boolean value for '%s'.\n",
-                                 item->name);
-                    parseMode = PM_ERROR;
-                }
-                else
-                {
-                    *(item->v.val_bool) = tmpBool;
-
-                    prevMode = parseMode;
-                    parseMode = PM_NORMAL;
-                }
-            }
-            c = -1;
-            break;
-        }
-    }
-
-    /* Check for validation errors */
-    if (validError)
-        return 1;
-
-    /* Return result */
-    if (parseMode == PM_ERROR)
-        return -2;
-    else
-        return 0;
-}
-
-
-int th_cfg_read(FILE *inFile, char *filename, cfgitem_t *cfg)
-{
-    conffile_t f;
-
-    f.file = inFile;
-    f.filename = filename;
-    f.line = 1;
-
-    return th_cfg_read_sect(&f, cfg, 0);
-}
-
-
-/* Write a configuration into file
- */
-static void th_print_indent(conffile_t *f, int nesting)
-{
-    int i;
-    for (i = 0; i < nesting * 2; i++)
-        fputc(' ', f->file);
-}
-
-
-static int th_cfg_write_sect(conffile_t *f, cfgitem_t *item, int nesting)
-{
-    while (item != NULL)
-    {
-        if (item->type == ITEM_COMMENT)
-        {
-            th_print_indent(f, nesting);
-            if (fprintf
-                (f->file, "# %s\n",
-                 (item->name != NULL) ? item->name : "") < 0)
-                return -1;
-        }
-        else if (item->name != NULL)
-        {
-            th_print_indent(f, nesting);
-
-            switch (item->type)
-            {
-            case ITEM_STRING:
-                if (*(item->v.val_str) == NULL)
-                {
-                    if (fprintf(f->file, "#%s = \"\"\n", item->name) < 0)
-                        return -3;
-                }
-                else
-                {
-                    if (fprintf(f->file, "%s = \"%s\"\n",
-                                item->name, *(item->v.val_str)) < 0)
-                        return -3;
-                }
-                break;
-
-            case ITEM_STRING_LIST:
-                if (*(item->v.list) == NULL)
-                {
-                    if (fprintf(f->file, "#%s = \"\", \"\"\n", item->name) <
-                        0)
-                        return -3;
-                }
-                else
-                {
-                    qlist_t *node = *(item->v.list);
-                    size_t n = th_llist_length(node);
-                    if (fprintf(f->file, "%s = ", item->name) < 0)
-                        return -3;
-
-                    while (node != NULL)
-                    {
-                        if (node->data != NULL)
-                            fprintf(f->file, "\"%s\"", (char *) node->data);
-
-                        if (--n > 0)
-                        {
-                            fprintf(f->file, ",\n");
-                            th_print_indent(f, nesting);
-                        }
-                        node = node->next;
-                    }
-
-                    if (fprintf(f->file, "\n") < 0)
-                        return -3;
-                }
-                break;
-
-            case ITEM_INT:
-                if (fprintf(f->file, "%s = %i\n",
-                            item->name, *(item->v.val_int)) < 0)
-                    return -4;
-                break;
-
-            case ITEM_UINT:
-                if (fprintf(f->file, "%s = %d\n",
-                            item->name, *(item->v.val_uint)) < 0)
-                    return -5;
-                break;
-
-            case ITEM_BOOL:
-                if (fprintf(f->file, "%s = %s\n",
-                            item->name,
-                            *(item->v.val_bool) ? "yes" : "no") < 0)
-                    return -6;
-                break;
-
-            case ITEM_SECTION:
-                {
-                    int res;
-                    if (fprintf(f->file, "%s = {\n", item->name) < 0)
-                        return -7;
-                    res = th_cfg_write_sect(f, item->v.section, nesting + 1);
-                    if (res != 0)
-                        return res;
-                    if (fprintf(f->file, "}\n\n") < 0)
-                        return -8;
-                }
-                break;
-
-            case ITEM_HEX_TRIPLET:
-                if (fprintf(f->file, "%s = \"%06x\"\n",
-                            item->name, *(item->v.val_int)) < 0)
-                    return -6;
-                break;
-            }
-        }
-        item = item->next;
-    }
-
-    return 0;
-}
-
-
-int th_cfg_write(FILE *outFile, char *filename, cfgitem_t *cfg)
-{
-    conffile_t f;
-
-    if (cfg == NULL)
-        return -1;
-
-    f.file = outFile;
-    f.filename = filename;
-    f.line = 1;
-
-    fprintf(outFile, "# Configuration written by %s %s\n\n",
-            th_prog_fullname, th_prog_version);
-
-    return th_cfg_write_sect(&f, cfg, 0);
-}
--- a/th_config.h	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Very simple configuration file handling
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2004-2008 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifndef _TH_CONFIG_H
-#define _TH_CONFIG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "th_util.h"
-#include <stdio.h>
-
-
-/* Definitions
- */
-enum ITEM_TYPE {
-    ITEM_SECTION = 1,
-    ITEM_COMMENT,
-    ITEM_STRING,
-    ITEM_INT,
-    ITEM_UINT,
-    ITEM_BOOL,
-    ITEM_FLOAT,
-    ITEM_HEX_TRIPLET,
-
-    ITEM_STRING_LIST,
-    ITEM_HEX_TRIPLET_LIST
-};
-
-
-typedef struct _cfgitem_t {
-    int  type;
-    char *name;
-    union {
-        int *val_int;
-        unsigned int *val_uint;
-        char **val_str;
-        BOOL *val_bool;
-
-        void *data;
-        qlist_t **list;
-        struct _cfgitem_t *section;
-    } v;
-    
-    struct _cfgitem_t *next, *prev;
-} cfgitem_t;
-
-
-/* Functions
- */
-int     th_cfg_read(FILE *, char *, cfgitem_t *);
-void    th_cfg_free(cfgitem_t *);
-int     th_cfg_write(FILE *, char *, cfgitem_t *);
-
-int     th_cfg_add_section(cfgitem_t **cfg, char *name, cfgitem_t *data);
-int     th_cfg_add_comment(cfgitem_t **cfg, char *comment);
-int     th_cfg_add_int(cfgitem_t **cfg, char *name, int *data, int itemDef);
-int     th_cfg_add_uint(cfgitem_t **cfg, char *name, unsigned int *data, unsigned int itemDef);
-int     th_cfg_add_string(cfgitem_t **cfg, char *name, char **data, char *itemDef);
-int     th_cfg_add_bool(cfgitem_t **cfg, char *name, BOOL *data, BOOL itemDef);
-int     th_cfg_add_float(cfgitem_t **cfg, char *name, float *data, float itemDef);
-int     th_cfg_add_hexvalue(cfgitem_t **cfg, char *name, int *data, int itemDef);
-
-int     th_cfg_add_string_list(cfgitem_t **cfg, char *name, qlist_t **list);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _TH_CONFIG_H */
--- a/th_string.c	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,577 +0,0 @@
-/*
- * Miscellaneous string-handling related utility-functions
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "th_string.h"
-
-/* strdup with a NULL check
- */
-char *th_strdup(const char *s)
-{
-    char *res;
-    if (s == NULL)
-        return NULL;
-
-    if ((res = th_malloc(strlen(s) + 1)) == NULL)
-        return NULL;
-
-    strcpy(res, s);
-    return res;
-}
-
-
-char *th_strncpy(char *dst, const char *src, const size_t n)
-{
-    const char *s = src;
-    char *d = dst;
-    size_t i;
-    assert(src != NULL);
-    assert(dst != NULL);
-
-    /* Copy to the destination */
-    i = n;
-    while (*s && i > 0)
-    {
-        *(d++) = *(s++);
-        i--;
-    }
-
-    /* Fill rest of space with zeros */
-    while (i > 0)
-    {
-        *(d++) = 0;
-        i--;
-    }
-
-    /* Ensure that last is always zero */
-    dst[n - 1] = 0;
-
-    return dst;
-}
-
-
-/* Simulate a sprintf() that allocates memory
- */
-char *th_strdup_vprintf(const char *fmt, va_list args)
-{
-    int size = 64;
-    char *buf, *nbuf = NULL;
-
-    if ((buf = th_malloc(size)) == NULL)
-        return NULL;
-
-    while (1)
-    {
-        int n;
-        va_list ap;
-        va_copy(ap, args);
-        n = vsnprintf(buf, size, fmt, ap);
-        va_end(ap);
-
-        if (n > -1 && n < size)
-            return buf;
-        if (n > -1)
-            size = n + 1;
-        else
-            size *= 2;
-
-        if ((nbuf = th_realloc(nbuf, size)) == NULL)
-        {
-            th_free(buf);
-            return NULL;
-        }
-
-        buf = nbuf;
-    }
-}
-
-
-char *th_strdup_printf(const char *fmt, ...)
-{
-    char *res;
-    va_list ap;
-
-    va_start(ap, fmt);
-    res = th_strdup_vprintf(fmt, ap);
-    va_end(ap);
-
-    return res;
-}
-
-
-void th_pstr_vprintf(char **buf, const char *fmt, va_list ap)
-{
-    char *tmp = th_strdup_vprintf(fmt, ap);
-    th_free(*buf);
-    *buf = tmp;
-}
-
-
-void th_pstr_printf(char **buf, const char *fmt, ...)
-{
-    char *tmp;
-    va_list ap;
-
-    va_start(ap, fmt);
-    tmp = th_strdup_vprintf(fmt, ap);
-    va_end(ap);
-
-    th_free(*buf);
-    *buf = tmp;
-}
-
-/* Compare two strings ignoring case [strcasecmp, strncasecmp]
- */
-int th_strcasecmp(const char *str1, const char *str2)
-{
-    const char *s1 = str1, *s2 = str2;
-    assert(str1 != NULL);
-    assert(str2 != NULL);
-
-    if (str1 == str2)
-        return 0;
-
-    while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2))
-    {
-        s1++;
-        s2++;
-    }
-
-    return (th_tolower(*s1) - th_tolower(*s2));
-}
-
-
-int th_strncasecmp(const char *str1, const char *str2, size_t n)
-{
-    const char *s1 = str1, *s2 = str2;
-    assert(str1 != NULL);
-    assert(str2 != NULL);
-
-    if (str1 == str2)
-        return 0;
-
-    while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2))
-    {
-        s1++;
-        s2++;
-        n--;
-    }
-
-    return n > 0 ? (th_tolower(*s1) - th_tolower(*s2)) : 0;
-}
-
-
-/* Remove all occurences of control characters, in-place.
- * Resulting string is always shorter or same length than original.
- */
-void th_strip_ctrlchars(char *str)
-{
-    char *i, *j;
-    assert(str != NULL);
-
-    i = str;
-    j = str;
-    while (*i)
-    {
-        if (!th_iscntrl(*i))
-            *(j++) = *i;
-        i++;
-    }
-
-    *j = 0;
-}
-
-
-/* Copy a given string over in *result.
- */
-int th_pstrcpy(char **result, const char *str)
-{
-    assert(result != NULL);
-
-    if (str == NULL)
-        return -1;
-
-    th_free(*result);
-    if ((*result = th_malloc(strlen(str) + 1)) == NULL)
-        return -2;
-
-    strcpy(*result, str);
-    return 0;
-}
-
-
-/* Concatenates a given string into string pointed by *result.
- */
-int th_pstrcat(char **result, const char *str)
-{
-    assert(result != NULL);
-
-    if (str == NULL)
-        return -1;
-
-    if (*result != NULL)
-    {
-        *result = th_realloc(*result, strlen(*result) + strlen(str) + 1);
-        if (*result == NULL)
-            return -1;
-
-        strcat(*result, str);
-    }
-    else
-    {
-        *result = th_malloc(strlen(str) + 1);
-        if (*result == NULL)
-            return -1;
-
-        strcpy(*result, str);
-    }
-
-    return 0;
-}
-
-
-/* Find next non-whitespace character in string.
- * Updates iPos into the position of such character and
- * returns pointer to the string.
- */
-const char *th_findnext(const char *str, size_t *pos)
-{
-    assert(str != NULL);
-
-    /* Terminating NULL-character is not whitespace! */
-    while (th_isspace(str[*pos]))
-        (*pos)++;
-
-    return &str[*pos];
-}
-
-
-/* Find next sep-character from string
- */
-const char *th_findsep(const char *str, size_t *pos, char sep)
-{
-    assert(str != NULL);
-
-    while (str[*pos] && str[*pos] != sep)
-        (*pos)++;
-
-    return &str[*pos];
-}
-
-
-/* Find next sep- or whitespace from string
- */
-const char *th_findseporspace(const char *str, size_t *pos, char sep)
-{
-    assert(str != NULL);
-
-    while (!th_isspace(str[*pos]) && str[*pos] != sep)
-        (*pos)++;
-
-    return &str[*pos];
-}
-
-
-/* Compare a string to a pattern. Case-SENSITIVE version.
- * The matching pattern can consist of any normal characters plus
- * wildcards ? and *. "?" matches any character and "*" matches
- * any number of characters.
- */
-BOOL th_strmatch(const char *str, const char *pattern)
-{
-    BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
-    const char *tmpPattern = NULL;
-
-    /* Check given pattern and string */
-    if (str == NULL || pattern == NULL)
-        return FALSE;
-
-    /* Start comparision */
-    do
-    {
-        didMatch = FALSE;
-        switch (*pattern)
-        {
-        case '?':
-            /* Any single character matches */
-            if (*str)
-            {
-                didMatch = TRUE;
-                pattern++;
-                str++;
-            }
-            break;
-
-        case '*':
-            didMatch = TRUE;
-            pattern++;
-            if (!*pattern)
-                isEnd = TRUE;
-            isAnyMode = TRUE;
-            tmpPattern = pattern;
-            break;
-
-        case 0:
-            if (isAnyMode)
-            {
-                if (*str)
-                    str++;
-                else
-                    isEnd = TRUE;
-            }
-            else
-            {
-                if (*str)
-                {
-                    if (tmpPattern)
-                    {
-                        isAnyMode = TRUE;
-                        pattern = tmpPattern;
-                    }
-                    else
-                        didMatch = FALSE;
-                }
-                else
-                    isEnd = TRUE;
-            }
-            break;
-        default:
-            if (isAnyMode)
-            {
-                if (*pattern == *str)
-                {
-                    isAnyMode = FALSE;
-                    didMatch = TRUE;
-                }
-                else
-                {
-                    if (*str)
-                    {
-                        didMatch = TRUE;
-                        str++;
-                    }
-                }
-            }
-            else
-            {
-                if (*pattern == *str)
-                {
-                    didMatch = TRUE;
-                    if (*pattern)
-                        pattern++;
-                    if (*str)
-                        str++;
-                }
-                else
-                {
-                    if (tmpPattern)
-                    {
-                        didMatch = TRUE;
-                        isAnyMode = TRUE;
-                        pattern = tmpPattern;
-                    }
-                }
-            }
-
-            if (!*str && !*pattern)
-                isEnd = TRUE;
-            break;
-
-        }                       /* switch */
-
-    }
-    while (didMatch && !isEnd);
-
-    return didMatch;
-}
-
-
-/* Compare a string to a pattern. Case-INSENSITIVE version.
- */
-BOOL th_strcasematch(const char *str, const char *pattern)
-{
-    BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
-    const char *tmpPattern = NULL;
-
-    /* Check given pattern and string */
-    if (str == NULL || pattern == NULL)
-        return FALSE;
-
-    /* Start comparision */
-    do
-    {
-        switch (*pattern)
-        {
-        case '?':
-            /* Any single character matches */
-            if (*str)
-            {
-                pattern++;
-                str++;
-            }
-            else
-                didMatch = FALSE;
-            break;
-
-        case '*':
-            pattern++;
-            if (!*pattern || *pattern == '?')
-                isEnd = TRUE;
-            isAnyMode = TRUE;
-            tmpPattern = pattern;
-            break;
-
-        case 0:
-            if (isAnyMode)
-            {
-                if (*str)
-                    str++;
-                else
-                    isEnd = TRUE;
-            }
-            else
-            {
-                if (*str)
-                {
-                    if (tmpPattern)
-                    {
-                        isAnyMode = TRUE;
-                        pattern = tmpPattern;
-                    }
-                    else
-                        didMatch = FALSE;
-                }
-                else
-                    isEnd = TRUE;
-            }
-            break;
-
-        default:
-            if (isAnyMode)
-            {
-                if (th_tolower(*pattern) == th_tolower(*str))
-                {
-                    isAnyMode = FALSE;
-                }
-                else
-                {
-                    if (*str)
-                        str++;
-                    else
-                        didMatch = FALSE;
-                }
-            }
-            else
-            {
-                if (th_tolower(*pattern) == th_tolower(*str))
-                {
-                    if (*pattern)
-                        pattern++;
-                    if (*str)
-                        str++;
-                }
-                else
-                {
-                    if (tmpPattern)
-                    {
-                        isAnyMode = TRUE;
-                        pattern = tmpPattern;
-                    }
-                    else
-                        didMatch = FALSE;
-                }
-            }
-
-            if (!*str && !*pattern)
-                isEnd = TRUE;
-
-            break;
-
-        }                       /* switch */
-
-    }
-    while (didMatch && !isEnd);
-
-    return didMatch;
-}
-
-
-int th_get_hex_triplet(const char *str)
-{
-    const char *p = str;
-    int len, val = 0;
-
-    for (len = 0; *p && len < 6; p++, len++)
-    {
-        if (*p >= '0' && *p <= '9')
-        {
-            val *= 16;
-            val += (*p - '0');
-        }
-        else if (*p >= 'A' && *p <= 'F')
-        {
-            val *= 16;
-            val += (*p - 'A') + 10;
-        }
-        else if (*p >= 'a' && *p <= 'f')
-        {
-            val *= 16;
-            val += (*p - 'a') + 10;
-        }
-        else
-            return -1;
-    }
-
-    return (len == 6) ? val : -1;
-}
-
-
-BOOL th_growbuf(char **buf, size_t *bufsize, size_t *len, size_t grow)
-{
-    if (*buf == NULL)
-        *bufsize = *len = 0;
-
-    if (*buf == NULL || *len + grow >= *bufsize)
-    {
-        *bufsize += grow + TH_BUFGROW;
-        *buf = (char *) th_realloc(*buf, *bufsize);
-        if (*buf == NULL)
-            return FALSE;
-    }
-    return TRUE;
-}
-
-
-BOOL th_vputch(char **buf, size_t *bufsize, size_t *len, const char ch)
-{
-    if (!th_growbuf(buf, bufsize, len, 1))
-        return FALSE;
-
-    (*buf)[*len] = ch;
-    (*len)++;
-
-    return TRUE;
-}
-
-
-BOOL th_vputs(char **buf, size_t *bufsize, size_t *len, const char *str)
-{
-    size_t slen;
-    if (str == NULL)
-        return FALSE;
-
-    slen = strlen(str);
-    if (!th_growbuf(buf, bufsize, len, slen))
-        return FALSE;
-
-    strcpy(*buf + *len, str);
-    (*len) += slen;
-
-    return TRUE;
-}
--- a/th_string.h	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Miscellaneous string-handling related utility-functions
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2011 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifndef _TH_STRING_H
-#define _TH_STRING_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "th_util.h"
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-/* Macros
- */
-#define th_isalnum(c)   isalnum((int)(unsigned char) c)
-#define th_isalpha(c)   isalpha((int)(unsigned char) c)
-#define th_isascii(c)   isascii((int)(unsigned char) c)
-#define th_isblank(c)   isblank((int)(unsigned char) c)
-#define th_iscntrl(c)   iscntrl((int)(unsigned char) c)
-#define th_isdigit(c)   isdigit((int)(unsigned char) c)
-#define th_isgraph(c)   isgraph((int)(unsigned char) c)
-#define th_islower(c)   islower((int)(unsigned char) c)
-#define th_isprint(c)   isprint((int)(unsigned char) c)
-#define th_ispunct(c)   ispunct((int)(unsigned char) c)
-#define th_isspace(c)   isspace((int)(unsigned char) c)
-#define th_isupper(c)   isupper((int)(unsigned char) c)
-#define th_isxdigit(c)  isxdigit((int)(unsigned char) c)
-#define th_iscrlf(c)    ((c=='\r')||(c=='\n'))
-
-#define th_isspecial(q) (((q >= 0x5b) && (q <= 0x60)) || ((q >= 0x7b) && (q <= 0x7d)))
-
-#define th_tolower(c)   tolower((int)(unsigned char) c)
-#define th_toupper(c)   toupper((int)(unsigned char) c)
-
-
-/* Normal NUL-terminated string functions
- */
-char    *th_strncpy(char *, const char *, size_t);
-int     th_strcasecmp(const char *, const char *);
-int     th_strncasecmp(const char *, const char *, size_t);
-void    th_strip_ctrlchars(char *);
-
-char    *th_strdup_vprintf(const char *, va_list);
-char    *th_strdup_printf(const char *, ...);
-
-void    th_pstr_vprintf(char **, const char *, va_list);
-void    th_pstr_printf(char **, const char *, ...);
-
-char    *th_strdup(const char *);
-int     th_pstrcpy(char **, const char *);
-int     th_pstrcat(char **, const char *);
-
-const char    *th_findnext(const char *, size_t *);
-const char    *th_findsep(const char *, size_t *, char);
-const char    *th_findseporspace(const char *, size_t *, char);
-
-BOOL    th_strmatch(const char *, const char *);
-BOOL    th_strcasematch(const char *, const char *);
-
-int     th_get_hex_triplet(const char *);
-
-
-BOOL    th_growbuf(char **buf, size_t *bufsize, size_t *len, size_t grow);
-BOOL    th_vputch(char **buf, size_t *bufsize, size_t *len, const char ch);
-BOOL    th_vputs(char **buf, size_t *bufsize, size_t *len, const char *str);
-
-#define TH_BUFGROW       (32)
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _TH_STRING_H */
--- a/th_types.h	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Type definations
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2008 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-/* If your code uses "config.h", you need to #include
- * it before including this header.
- */
-#ifndef _TH_TYPES_H
-#define _TH_TYPES_H
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#ifndef HAVE_INT_TYPES
-#define HAVE_INT_TYPES 1
-#endif
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#ifndef HAVE_INT_TYPES
-#define HAVE_INT_TYPES 1
-#endif
-#endif
-
-/* Shorthand types */
-typedef unsigned long int ulint_t;
-typedef signed long int lint_t;
-#ifndef HAVE_UINT_T
-typedef unsigned int uint_t;
-#endif
-
-/* Default assumptions for these types should be ok for most 32bit platforms...
- * feel free to define TH_TYPE_* if necessary to remedy
- */
-#ifdef TH_TYPE_I8
-typedef unsigned TH_TYPE_I8 uint8_t;    /* 8 bits, unsigned */
-typedef signed TH_TYPE_I8 int8_t;    /* 8 bits, signed */
-#else
-#ifndef HAVE_INT_TYPES
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-#endif
-#endif
-
-
-#ifdef TH_TYPE_I16
-typedef unsigned TH_TYPE_I16 uint16_t;    /* 16 bits, unsigned == 2 BYTEs */
-typedef signed TH_TYPE_I16 int16_t;    /* 16 bits, signed */
-#else
-#ifndef HAVE_INT_TYPES
-typedef unsigned short int uint16_t;
-typedef signed short int int16_t;
-#endif
-#endif
-
-#ifdef TH_TYPE_I32
-typedef unsigned TH_TYPE_I32 uint32_t;    /* 32 bits, unsigned == 4 BYTES == 2 WORDs */
-typedef signed TH_TYPE_I32 int32_t;    /* 32 bits, signed */
-#else
-#ifndef HAVE_INT_TYPES
-typedef unsigned int uint32_t;
-typedef signed int int32_t;
-#endif
-#endif
-
-#ifdef TH_TYPE_I64
-typedef unsigned TH_TYPE_I64 uint64_t;    /* 64 bits, unsigned == 8 BYTES == 2 DWORDs */
-typedef signed TH_TYPE_I64 int64_t;    /* 64 bits, signed */
-#else
-#ifndef HAVE_INT_TYPES
-typedef unsigned long long uint64_t;
-typedef signed long long int64_t;
-#endif
-#endif
-
-
-/* This is the character type used in all string-related routines of
- * th_libs. Currently it is set to be equivalent of basetype "char",
- * but under some platforms it may be necessary to use
- * "unsigned char" instead.
- *
- * Also in future this type may be changed to hold 32-bit UNICODE
- */
-typedef char char_t;
-
-
-/* Define a boolean type
- */
-#if !defined(FALSE) && !defined(TRUE) && !defined(BOOL)
-typedef enum { FALSE = 0, TRUE = 1 } BOOL;
-#endif
-
-#ifndef BOOL
-#ifdef bool
-#define BOOL bool
-#else
-#define BOOL int
-#endif
-#endif
-
-#endif /* _TH_TYPES_H */
--- a/th_util.c	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,448 +0,0 @@
-/*
- * Generic utility-functions, macros and defaults
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2010 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include "th_util.h"
-#include <stdio.h>
-
-/* Default settings
- */
-static BOOL    th_initialized = FALSE;
-int    th_verbosityLevel = 2;
-char    *th_prog_name = NULL,
-    *th_prog_fullname = NULL,
-    *th_prog_version = NULL,
-    *th_prog_author = NULL,
-    *th_prog_license = NULL;
-
-
-/* Initialize th_util-library and global variables
- */
-void th_init(char *progName, char *progFullName, char *progVersion,
-    char *progAuthor, char *progLicense)
-{
-    th_prog_name = progName;
-    th_prog_fullname = progFullName;
-    th_prog_version = progVersion;
-
-    if (progAuthor)
-        th_prog_author = progAuthor;
-    else
-        th_prog_author = TH_PROG_AUTHOR;
-
-    if (progLicense)
-        th_prog_license = progLicense;
-    else
-        th_prog_license = TH_PROG_LICENSE;
-
-    th_initialized = TRUE;
-}
-
-
-/* Print formatted error, warning and information messages
- * TODO: Implement th_vfprintf() and friends?
- */
-void THERR_V(const char *fmt, va_list ap)
-{
-    assert(th_initialized == TRUE);
-
-    fprintf(stderr, "%s: ", th_prog_name);
-    vfprintf(stderr, fmt, ap);
-}
-
-
-void THMSG_V(int level, const char *fmt, va_list ap)
-{
-    assert(th_initialized == TRUE);
-
-    if (th_verbosityLevel >= level) {
-        fprintf(stderr, "%s: ", th_prog_name);
-        vfprintf(stderr, fmt, ap);
-    }
-}
-
-
-void THPRINT_V(int level, const char *fmt, va_list ap)
-{
-    assert(th_initialized == TRUE);
-
-    if (th_verbosityLevel >= level) {
-        vfprintf(stderr, fmt, ap);
-    }
-}
-
-
-void THERR(const char *fmt, ...)
-{
-    va_list ap;
-    assert(th_initialized == TRUE);
-
-    va_start(ap, fmt);
-    THERR_V(fmt, ap);
-    va_end(ap);
-}
-
-
-void THMSG(int level, const char *fmt, ...)
-{
-    va_list ap;
-    assert(th_initialized == TRUE);
-
-    va_start(ap, fmt);
-    THMSG_V(level, fmt, ap);
-    va_end(ap);
-}
-
-
-void THPRINT(int level, const char *fmt, ...)
-{
-    va_list ap;
-    assert(th_initialized == TRUE);
-
-    va_start(ap, fmt);
-    THPRINT_V(level, fmt, ap);
-    va_end(ap);
-}
-
-
-/* Memory handling routines
- */
-void *th_malloc(size_t l)
-{
-    return malloc(l);
-}
-
-
-void *th_calloc(size_t n, size_t l)
-{
-    return calloc(n, l);
-}
-
-
-void *th_realloc(void *p, size_t l)
-{
-    return realloc(p, l);
-}
-
-
-void th_free(void *p)
-{
-    /* Check for NULL pointers for portability due to some libc
-     * implementations not handling free(NULL) too well.
-     */
-    if (p) free(p);
-}
-
-
-#ifndef HAVE_MEMSET
-void *th_memset(void *p, int c, size_t n)
-{
-    unsigned char *dp = (unsigned char *) p;
-    
-    while (n--)
-        *(dp++) = c;
-
-    return p;
-}
-#endif
-
-
-/* Doubly linked list handling
- *
- * In this implementation first node's prev points to last node of the list,
- * and last node's next is NULL. This way we can semi-efficiently traverse to
- * beginning and end of the list, assuming user does not do weird things.
- */
-qlist_t * th_llist_new(void *data)
-{
-    qlist_t *res = th_calloc(sizeof(qlist_t), 1);
-    res->data = data;
-    return res;
-}
-
-void th_llist_free_func(qlist_t *list, void (*freefunc)(void *data))
-{
-    qlist_t *curr = list;
-
-    while (curr != NULL) {
-        qlist_t *next = curr->next;
-        if (freefunc != NULL && curr->data != NULL)
-            freefunc(curr->data);
-        th_free(curr);
-        curr = next;
-    }
-}
-
-
-void th_llist_free(qlist_t *list)
-{
-    th_llist_free_func(list, NULL);
-}
-
-void th_llist_append_node(qlist_t **list, qlist_t *node)
-{
-    if (*list != NULL) {
-        node->prev = (*list)->prev;
-        (*list)->prev->next = node;
-        (*list)->prev = node;
-        (*list)->num++;
-    } else {
-        *list = node;
-        node->prev = *list;
-        (*list)->num = 1;
-    }
-
-    node->next = NULL;
-}
-
-
-qlist_t *th_llist_append(qlist_t **list, void *data)
-{
-    qlist_t *node = th_llist_new(data);
-
-    th_llist_append_node(list, node);
-
-    return node;
-}
-
-
-void th_llist_prepend_node(qlist_t **list, qlist_t *node)
-{
-    if (*list != NULL) {
-        node->prev = (*list)->prev;
-        node->next = *list;
-        (*list)->prev = node;
-        node->num = (*list)->num + 1;
-        *list = node;
-    } else {
-        *list = node->prev = node;
-        node->next = NULL;
-        (*list)->num = 1;
-    }
-
-}
-
-
-qlist_t *th_llist_prepend(qlist_t **list, void *data)
-{
-    qlist_t *node = th_llist_new(data);
-
-    th_llist_prepend_node(list, node);
-
-    return node;
-}
-
-/*
-1) Remove a middle node
-
-    node0->prev->next = node->next (node1)
-    node0->next->prev = node->prev (list)
-
-    node2 <- list <=> node0 <=> node1 <=> node2 -> NULL
-    node2 <- list <=> node1 <=> node2 -> NULL
-
-2) Remove first node when many items
-
-
-    node2 <- list <=> node0 <=> node1 <=> node2 -> NULL
-    node2 <- node0 <=> node1 <=> node2 -> NULL
-
-    *list = node0
-
-3) Remove last node in list
-
-    if (node->next == NULL) {
-        list->prev = node->prev;
-        node->prev->next = NULL;
-    }
-
-    node2 <- list <=> node0 <=> node1 <=> node2 -> NULL
-    node1 <- list <=> node0 <=> node1 -> NULL
-
-4) Remove last
-
-    list <- list -> NULL
-    
-    
-*/
-static void th_llist_delete_node_fast(qlist_t **list, qlist_t *node)
-{
-    if (node == *list) {
-        /* First node in list */
-        qlist_t *tmp = (*list)->next;
-        if (tmp != NULL) {
-            tmp->num = (*list)->num - 1;
-            tmp->prev = (*list)->prev;
-        }
-        *list = tmp;
-    } else {
-        /* Somewhere in middle or end */
-        if (node->prev != NULL)
-            node->prev->next = node->next;
-
-        if (node->next != NULL)
-            node->next->prev = node->prev;
-        else
-            (*list)->prev = node; /* Last node */
-
-        (*list)->num--;
-    }
-    
-    node->next = node->prev = NULL;
-}
-
-
-void th_llist_delete_node(qlist_t **list, qlist_t *node)
-{
-    qlist_t *curr = *list;
-
-    while (curr != NULL) {
-        qlist_t *next = curr->next;
-        if (curr == node) {
-            th_llist_delete_node_fast(list, curr);
-            th_free(node);
-            break;
-        }
-        curr = next;
-    }
-}
-
-
-void th_llist_delete(qlist_t **list, const void *data)
-{
-    qlist_t *curr = *list;
-
-    while (curr != NULL) {
-        qlist_t *next = curr->next;
-        if (curr->data == data) {
-            th_llist_delete_node_fast(list, curr);
-            th_free(curr);
-            break;
-        }
-        curr = next;
-    }
-}
-
-
-qlist_t * th_llist_get_nth(qlist_t *list, const size_t n)
-{
-    qlist_t *curr = list;
-    size_t i;
-
-    for (i = 0; curr != NULL && i < n; curr = curr->next, i++);
-
-    return curr;
-}
-
-
-size_t th_llist_length(const qlist_t *list)
-{
-    if (list == NULL)
-        return 0;
-    else
-        return list->num;
-}
-
-
-ssize_t th_llist_position(const qlist_t *list, const qlist_t *node)
-{
-    const qlist_t *curr = list;
-    ssize_t i = 0;
-
-    while (curr != NULL) {
-        if (curr == node)
-            return i;
-        else
-            i++;
-
-        curr = curr->next;
-    }
-    
-    return -1;
-}
-
-
-qlist_t * th_llist_find(qlist_t *list, const void *data)
-{
-    qlist_t *curr = list;
-
-    while (curr != NULL) {
-        if (curr->data == data)
-            return curr;
-        curr = curr->next;
-    }
-
-    return NULL;
-}
-
-
-qlist_t * th_llist_find_func(qlist_t *list, const void *userdata, int (compare)(const void *, const void *))
-{
-    qlist_t *curr = list;
-
-    while (curr != NULL) {
-        if (compare(curr->data, userdata) == 0)
-            return curr;
-        curr = curr->next;
-    }
-
-    return NULL;
-}
-
-
-/*
- * Ringbuffers
- */
-qringbuf_t * th_ringbuf_new(const size_t size, void (*mdeallocator)(void *data))
-{
-    qringbuf_t *res = th_calloc(1, sizeof(qringbuf_t));
-    
-    res->data = (char **) th_calloc(size, sizeof(char *));
-    res->size = size;
-    res->n = 0;
-    res->deallocator = mdeallocator;
-    
-    return res;
-}
-
-
-BOOL th_ringbuf_grow(qringbuf_t *buf, const size_t n)
-{
-    buf->data = (char **) th_realloc(buf->data, (buf->size + n) * sizeof(char *));
-    if (buf->data != NULL) {
-        memset(buf->data + buf->size, 0, sizeof(char *) * n);
-        buf->size += n;
-        return TRUE;
-    } else
-        return FALSE;
-}
-
-
-void th_ringbuf_free(qringbuf_t *buf)
-{
-    int i;
-    
-    for (i = 0; i < buf->size; i++)
-        if (buf->data[i] != NULL)
-            buf->deallocator(buf->data[i]);
-    
-    th_free(buf->data);
-    th_free(buf);
-}
-
-
-void th_ringbuf_add(qringbuf_t *buf, void *ptr)
-{
-    if (buf->n < buf->size)
-        buf->n++;
-
-    th_free(buf->data[0]);
-    memmove(&(buf->data[0]), &(buf->data[1]), (buf->size - 1) * sizeof(void *));
-    buf->data[buf->size - 1] = ptr;
-}
--- a/th_util.h	Mon Oct 03 15:43:01 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Generic utility-functions, macros and defaults
- * Programmed and designed by Matti 'ccr' Hamalainen
- * (C) Copyright 2002-2010 Tecnic Software productions (TNSP)
- *
- * Please read file 'COPYING' for information on license and distribution.
- */
-#ifndef _TH_UTIL_H
-#define _TH_UTIL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "th_types.h"
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifndef HAVE_NO_ASSERT
-#include <assert.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#define HAVE_MEMSET 1
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
-
-
-#ifdef TH_NO_DEFAULTS
-#define TH_PROG_AUTHOR      NULL
-#define TH_PROG_LICENSE     NULL
-#else
-#define TH_PROG_AUTHOR      "By Matti 'ccr' Hämäläinen (C) Copyright 2011 TNSP"
-#define TH_PROG_LICENSE     "This software is licensed under GNU GPL version 2"
-#endif
-
-
-/* Replacement for assert() */
-#ifdef HAVE_NO_ASSERT
-#  ifdef NDEBUG
-#    define assert(NEXPR) /* stub */
-#  else
-#    define assert(NEXPR) do { if (!(NEXPR)) { fprintf(stderr, "[%s:%d] assert(" # NEXPR ") failed!\n", __FILE__, __LINE__); abort(); } } while (0)
-#  endif
-#endif
-
-/* Global variables
- */
-extern int  th_verbosityLevel;
-extern char *th_prog_name,
-            *th_prog_fullname,
-            *th_prog_version,
-            *th_prog_author,
-            *th_prog_license;
-
-/* Functions
- */
-void    th_init(char *progName, char *progFullName, char *progVersion,
-               char *progAuthor, char *progLicense);
-void    THERR(const char *, ...);
-void    THMSG(int, const char *, ...);
-void    THPRINT(int, const char *, ...);
-
-void    THERR_V(const char *, va_list);
-void    THMSG_V(int, const char *, va_list);
-void    THPRINT_V(int, const char *, va_list);
-
-void    *th_malloc(size_t);
-void    *th_calloc(size_t, size_t);
-void    *th_realloc(void *, size_t);
-void    th_free(void *);
-
-#ifdef HAVE_MEMSET
-#define th_memset memset
-#else
-void    *th_memset(void *, int, size_t);
-#endif
-
-
-/* Doubly linked list handling
- */
-typedef struct _qlist_t {
-    void *data;
-    size_t num;
-    struct _qlist_t *prev, *next;
-} qlist_t;
-
-
-qlist_t * th_llist_new(void *data);
-void      th_llist_free(qlist_t *list);
-void      th_llist_free_func(qlist_t *list, void (*freefunc)(void *data));
-
-qlist_t * th_llist_append(qlist_t **list, void *data);
-qlist_t * th_llist_prepend(qlist_t **list, void *data);
-void      th_llist_delete(qlist_t **list, const void *data);
-void      th_llist_delete_node(qlist_t **list, qlist_t *node);
-
-qlist_t * th_llist_get_nth(qlist_t *list, const size_t n);
-size_t    th_llist_length(const qlist_t *list);
-ssize_t   th_llist_position(const qlist_t *list, const qlist_t *node);
-
-qlist_t * th_llist_find(qlist_t *list, const void *data);
-qlist_t * th_llist_find_func(qlist_t *list, const void *userdata, int (compare)(const void *, const void *));
-
-
-/* Ringbuffer implementation
- */
-typedef struct {
-    char **data;
-    int n, size;
-    void (*deallocator)(void *);
-} qringbuf_t;
-
-qringbuf_t * th_ringbuf_new(const size_t size, void (*mdeallocator)(void *));
-BOOL        th_ringbuf_grow(qringbuf_t *buf, const size_t n);
-void        th_ringbuf_free(qringbuf_t *buf);
-void        th_ringbuf_add(qringbuf_t *buf, void *ptr);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _TH_UTIL_H */