summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/amd64.asm.in38
-rw-r--r--lib/atomic.h2716
-rw-r--r--lib/base/x11/keysym.nim1900
-rw-r--r--lib/contnrs.nim11
-rw-r--r--lib/dlmalloc.c5076
-rw-r--r--lib/dlmalloc.h1143
-rw-r--r--lib/generics.nim169
-rw-r--r--lib/i386.asm.in70
-rw-r--r--lib/impure/dialogs.nim (renamed from lib/base/dialogs.nim)0
-rw-r--r--lib/impure/web.nim (renamed from lib/base/web.nim)0
-rw-r--r--lib/impure/zipfiles.nim (renamed from lib/base/zip/zipfiles.nim)0
-rw-r--r--lib/int64s.nim71
-rw-r--r--lib/locks.nim18
-rw-r--r--lib/posix/detect.nim824
-rw-r--r--lib/posix/linux_amd64_consts.nim620
-rw-r--r--lib/posix/linux_consts.nim620
-rw-r--r--lib/posix/posix.nim59
-rw-r--r--lib/powerpc.asm.in35
-rw-r--r--lib/pure/cgi.nim (renamed from lib/base/cgi.nim)0
-rw-r--r--lib/pure/complex.nim (renamed from lib/complex.nim)0
-rw-r--r--lib/pure/dynlib.nim84
-rw-r--r--lib/pure/hashes.nim (renamed from lib/hashes.nim)0
-rw-r--r--lib/pure/lexbase.nim (renamed from lib/lexbase.nim)0
-rw-r--r--lib/pure/macros.nim (renamed from lib/macros.nim)18
-rw-r--r--lib/pure/math.nim (renamed from lib/math.nim)2
-rw-r--r--lib/pure/md5.nim245
-rw-r--r--lib/pure/os.nim (renamed from lib/os.nim)998
-rw-r--r--lib/pure/osproc.nim (renamed from lib/osproc.nim)0
-rw-r--r--lib/pure/parsecfg.nim (renamed from lib/parsecfg.nim)3
-rw-r--r--lib/pure/parsecsv.nim (renamed from lib/parsecsv.nim)2
-rw-r--r--lib/pure/parseopt.nim (renamed from lib/parseopt.nim)0
-rw-r--r--lib/pure/parsesql.nim1333
-rw-r--r--lib/pure/parsexml.nim (renamed from lib/parsexml.nim)14
-rw-r--r--lib/pure/regexprs.nim (renamed from lib/base/regexprs.nim)0
-rw-r--r--lib/pure/streams.nim (renamed from lib/streams.nim)0
-rw-r--r--lib/pure/strtabs.nim (renamed from lib/strtabs.nim)0
-rw-r--r--lib/pure/strutils.nim (renamed from lib/strutils.nim)11
-rw-r--r--lib/pure/terminal.nim (renamed from lib/base/terminal.nim)0
-rw-r--r--lib/pure/times.nim (renamed from lib/times.nim)36
-rw-r--r--lib/pure/unicode.nim (renamed from lib/unicode.nim)2
-rw-r--r--lib/pure/xmlgen.nim (renamed from lib/xmlgen.nim)0
-rw-r--r--lib/system.nim57
-rw-r--r--lib/system/alloc.nim (renamed from lib/alloc.nim)0
-rw-r--r--lib/system/ansi_c.nim (renamed from lib/ansi_c.nim)17
-rw-r--r--lib/system/arithm.nim (renamed from lib/arithm.nim)0
-rw-r--r--lib/system/assign.nim (renamed from lib/assign.nim)0
-rw-r--r--lib/system/cellsets.nim (renamed from lib/cellsets.nim)0
-rw-r--r--lib/system/cntbits.nim (renamed from lib/cntbits.nim)0
-rw-r--r--lib/system/debugger.nim (renamed from lib/debugger.nim)0
-rw-r--r--lib/system/dyncalls.nim (renamed from lib/dyncalls.nim)23
-rw-r--r--lib/system/ecmasys.nim (renamed from lib/ecmasys.nim)2
-rw-r--r--lib/system/excpt.nim (renamed from lib/excpt.nim)0
-rw-r--r--lib/system/gc.nim (renamed from lib/gc.nim)0
-rw-r--r--lib/system/hti.nim (renamed from lib/hti.nim)39
-rw-r--r--lib/system/mm.nim (renamed from lib/mm.nim)10
-rw-r--r--lib/system/profiler.nim (renamed from lib/profiler.nim)0
-rw-r--r--lib/system/repr.nim (renamed from lib/repr.nim)0
-rw-r--r--lib/system/sets.nim (renamed from lib/sets.nim)2
-rw-r--r--lib/system/sysio.nim (renamed from lib/sysio.nim)6
-rw-r--r--lib/system/sysstr.nim (renamed from lib/sysstr.nim)0
-rw-r--r--lib/target.h12
-rw-r--r--lib/tlsf.c1005
-rw-r--r--lib/tlsf.h39
-rw-r--r--lib/tlsfnim.nim698
-rw-r--r--lib/windows/winlean.nim (renamed from lib/winlean.nim)80
-rw-r--r--lib/wrappers/cairo/cairo.nim (renamed from lib/base/cairo/cairo.nim)0
-rw-r--r--lib/wrappers/cairo/cairoft.nim (renamed from lib/base/cairo/cairoft.nim)0
-rw-r--r--lib/wrappers/cairo/cairowin32.nim (renamed from lib/base/cairo/cairowin32.nim)0
-rw-r--r--lib/wrappers/cairo/cairoxlib.nim (renamed from lib/base/cairo/cairoxlib.nim)0
-rw-r--r--lib/wrappers/gtk/atk.nim (renamed from lib/base/gtk/atk.nim)0
-rw-r--r--lib/wrappers/gtk/gdk2.nim (renamed from lib/base/gtk/gdk2.nim)0
-rw-r--r--lib/wrappers/gtk/gdk2pixbuf.nim (renamed from lib/base/gtk/gdk2pixbuf.nim)0
-rw-r--r--lib/wrappers/gtk/gdkglext.nim (renamed from lib/base/gtk/gdkglext.nim)0
-rw-r--r--lib/wrappers/gtk/glib2.nim (renamed from lib/base/gtk/glib2.nim)0
-rw-r--r--lib/wrappers/gtk/gtk2.nim (renamed from lib/base/gtk/gtk2.nim)0
-rw-r--r--lib/wrappers/gtk/gtkglext.nim (renamed from lib/base/gtk/gtkglext.nim)0
-rw-r--r--lib/wrappers/gtk/gtkhtml.nim (renamed from lib/base/gtk/gtkhtml.nim)0
-rw-r--r--lib/wrappers/gtk/libglade2.nim (renamed from lib/base/gtk/libglade2.nim)0
-rw-r--r--lib/wrappers/gtk/pango.nim (renamed from lib/base/gtk/pango.nim)0
-rw-r--r--lib/wrappers/gtk/pangoutils.nim (renamed from lib/base/gtk/pangoutils.nim)0
-rw-r--r--lib/wrappers/libcurl.nim (renamed from lib/base/libcurl.nim)0
-rw-r--r--lib/wrappers/lua/lauxlib.nim (renamed from lib/base/lua/lauxlib.nim)2
-rw-r--r--lib/wrappers/lua/lua.nim (renamed from lib/base/lua/lua.nim)12
-rw-r--r--lib/wrappers/lua/lualib.nim (renamed from lib/base/lua/lualib.nim)2
-rw-r--r--lib/wrappers/mysql.nim (renamed from lib/base/mysql.nim)0
-rw-r--r--lib/wrappers/odbcsql.nim (renamed from lib/base/odbcsql.nim)0
-rw-r--r--lib/wrappers/opengl/gl.nim (renamed from lib/base/opengl/gl.nim)0
-rw-r--r--lib/wrappers/opengl/gl.pp (renamed from lib/base/opengl/gl.pp)0
-rw-r--r--lib/wrappers/opengl/glext.nim (renamed from lib/base/opengl/glext.nim)0
-rw-r--r--lib/wrappers/opengl/glext.pp (renamed from lib/base/opengl/glext.pp)0
-rw-r--r--lib/wrappers/opengl/glu.nim (renamed from lib/base/opengl/glu.nim)0
-rw-r--r--lib/wrappers/opengl/glu.pp (renamed from lib/base/opengl/glu.pp)0
-rw-r--r--lib/wrappers/opengl/glut.nim (renamed from lib/base/opengl/glut.nim)0
-rw-r--r--lib/wrappers/opengl/glut.pp (renamed from lib/base/opengl/glut.pp)0
-rw-r--r--lib/wrappers/opengl/glx.nim (renamed from lib/base/opengl/glx.nim)0
-rw-r--r--lib/wrappers/opengl/glx.pp (renamed from lib/base/opengl/glx.pp)0
-rw-r--r--lib/wrappers/opengl/wingl.nim (renamed from lib/base/opengl/wingl.nim)0
-rw-r--r--lib/wrappers/opengl/wingl.pp (renamed from lib/base/opengl/wingl.pp)0
-rw-r--r--lib/wrappers/pcre/pcre.nim (renamed from lib/base/pcre.nim)2
-rw-r--r--lib/wrappers/pcre/pcre_all.c (renamed from lib/base/pcre_all.c)0
-rw-r--r--lib/wrappers/postgres.nim (renamed from lib/base/postgres.nim)4
-rw-r--r--lib/wrappers/python.nim1581
-rw-r--r--lib/wrappers/sdl/sdl.nim (renamed from lib/base/sdl/sdl.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_gfx.nim (renamed from lib/base/sdl/sdl_gfx.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_image.nim (renamed from lib/base/sdl/sdl_image.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_mixer.nim (renamed from lib/base/sdl/sdl_mixer.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_mixer_nosmpeg.nim (renamed from lib/base/sdl/sdl_mixer_nosmpeg.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_net.nim (renamed from lib/base/sdl/sdl_net.nim)0
-rw-r--r--lib/wrappers/sdl/sdl_ttf.nim (renamed from lib/base/sdl/sdl_ttf.nim)0
-rw-r--r--lib/wrappers/sdl/sdlutils.pas (renamed from lib/base/sdl/sdlutils.pas)0
-rw-r--r--lib/wrappers/sdl/smpeg.nim (renamed from lib/base/sdl/smpeg.nim)0
-rw-r--r--lib/wrappers/sqlite3.nim (renamed from lib/base/sqlite3.nim)0
-rw-r--r--lib/wrappers/tcl.nim855
-rw-r--r--lib/wrappers/x11/cursorfont.nim (renamed from lib/base/x11/cursorfont.nim)0
-rw-r--r--lib/wrappers/x11/keysym.nim1925
-rw-r--r--lib/wrappers/x11/x.nim (renamed from lib/base/x11/x.nim)0
-rw-r--r--lib/wrappers/x11/xatom.nim (renamed from lib/base/x11/xatom.nim)0
-rw-r--r--lib/wrappers/x11/xcms.nim (renamed from lib/base/x11/xcms.nim)0
-rw-r--r--lib/wrappers/x11/xf86dga.nim (renamed from lib/base/x11/xf86dga.nim)0
-rw-r--r--lib/wrappers/x11/xf86vmode.nim (renamed from lib/base/x11/xf86vmode.nim)0
-rw-r--r--lib/wrappers/x11/xi.nim (renamed from lib/base/x11/xi.nim)0
-rw-r--r--lib/wrappers/x11/xinerama.nim (renamed from lib/base/x11/xinerama.nim)0
-rw-r--r--lib/wrappers/x11/xkb.nim (renamed from lib/base/x11/xkb.nim)0
-rw-r--r--lib/wrappers/x11/xkblib.nim (renamed from lib/base/x11/xkblib.nim)0
-rw-r--r--lib/wrappers/x11/xlib.nim (renamed from lib/base/x11/xlib.nim)0
-rw-r--r--lib/wrappers/x11/xrandr.nim (renamed from lib/base/x11/xrandr.nim)0
-rw-r--r--lib/wrappers/x11/xrender.nim (renamed from lib/base/x11/xrender.nim)0
-rw-r--r--lib/wrappers/x11/xresource.nim (renamed from lib/base/x11/xresource.nim)0
-rw-r--r--lib/wrappers/x11/xshm.nim (renamed from lib/base/x11/xshm.nim)0
-rw-r--r--lib/wrappers/x11/xutil.nim (renamed from lib/base/x11/xutil.nim)0
-rw-r--r--lib/wrappers/x11/xv.nim (renamed from lib/base/x11/xv.nim)0
-rw-r--r--lib/wrappers/x11/xvlib.nim (renamed from lib/base/x11/xvlib.nim)0
-rw-r--r--lib/wrappers/zip/libzip.nim (renamed from lib/base/zip/libzip.nim)0
-rw-r--r--lib/wrappers/zip/libzip_all.c (renamed from lib/base/zip/libzip_all.c)0
-rw-r--r--lib/wrappers/zip/zlib.nim (renamed from lib/base/zip/zlib.nim)0
-rw-r--r--lib/wrappers/zip/zzip.nim (renamed from lib/base/zip/zzip.nim)0
136 files changed, 6737 insertions, 15754 deletions
diff --git a/lib/amd64.asm.in b/lib/amd64.asm.in
deleted file mode 100644
index 0fa66fa7d..000000000
--- a/lib/amd64.asm.in
+++ /dev/null
@@ -1,38 +0,0 @@
-; This contains the CPU-dependant variants of some routines.

-; (C) 2005 Andreas Rumpf

-; This code was inspired by the Freepascal compiler's sources

-; All routines here have the _cdecl calling convention because

-; that is the only convention any C compiler supports.

-

-\python{

-import os

-

-def c(name): 

-  if os.name == 'posix':

-    return name

-  else:

-    return "_" + name

-    

-def arg:

-  if os.name == 'posix':

-    return 'rdi'

-  else:

-    return 'rcx' # on win64 uses its own calling convention; this sucks!

-}

-

-segment code

-

-global \c{cpu_inc_locked}

-global \c{cpu_dec_locked}

-

-\c{cpu_dec_locked}: 

-     lock

-     dec       [\arg]

-     setz      al

-     ret

-     

-\c{cpu_inc_locked}:

-     lock

-     inc       [\arg]

-     setz      al

-     ret

diff --git a/lib/atomic.h b/lib/atomic.h
deleted file mode 100644
index afab4843f..000000000
--- a/lib/atomic.h
+++ /dev/null
@@ -1,2716 +0,0 @@
-/* Atomic operations for Nimrod */
-
-#if defined(_MSCVER)
-__declspec(naked) int __fastcall Xadd (volatile int* pNum, int val)
-{
-    __asm
-    {
-        lock xadd dword ptr [ECX], EDX
-        mov EAX, EDX
-        ret
-    }
-}
-
-
-
-#endif
-
-
-#define ATOMIC_ASM(type,op)     \
-    __asm __volatile ("lock; " op : "=m" (*(type *)p) : "ir" (v), "0" (*(type *)p))
-
-#define ATOMIC_ASM_NOLOCK(type,op)     \
-    __asm __volatile (op : "=m" (*(type *)p) : "ir" (v), "0" (*(type *)p))
-
-static __inline void
-atomic_add_int(void *p, u_int v)
-{
-        ATOMIC_ASM(int, "addl %1,%0");
-}
-
-static __inline void
-atomic_add_int_nolock(void *p, u_int v)
-{
-        ATOMIC_ASM_NOLOCK(int, "addl %1,%0");
-}
-
-
-
-/*
-Atomic.h
-
-Joshua Scholar
-May 26, 2003
-
-This header contains:
-
-a multiprocessor nonblocking FIFO,  
-
-a multiprocessor nonblocking LIFO
-
-multiprocessor nonblocking reference counting (including volatile pointers 
-that can be safely shared between processors)
-
-nonblocking memory allocation routines
-
-template types that encapsulate variables meant to be shared between 
-processors - all changes to these variables are atomic and globally visible
-
-All kinds of atomic operations that are useful in a multiprocessor context.
-
-The philosophy behind this code is that I created templates that encapsulate
-atomic access so that while the templates themselves may not be the easiest
-code to read, code that uses these templates can be simple, abstract and
-reliable.
-
-I also created regular C style functions, overloaded by type for some of
-the more basic operations.  If you have regular variables or memory 
-locations that you want to use in a globally visible way you have two 
-choices.
-
-If the operation you want is one of the basic building blocks you can
-call one of the overloaded functions like InterlockedSetIfEqual().
-
-Otherwise it's perfectly safe to cast a pointer to your data to be a pointer
-to one of the atomic types so that you can use their methods.  For instance:
-if (((AtomicInt *)foo)->CompareSomeBitsAndExchangeSomeOtherBits(exchange, 
-        bitsToExchange,
-        comperand, 
-        bitsToCompare))
-    ...
-or even
-
-//atomically allocate n bytes out of the pool
- data = ((*(AtomicPtr<char> *)curPool)+= n) - n;
-
-
-
-State of code:
-
-Unlike other libraries of similar routines that I wrote in the past, this
-has not been thoroughly tested. In fact I don't remember how much of it has
-been tested at this point.
-
-It would take an 8 way machine for me to really pound on the routines.
-
-
-
-Overview
-
-Some basic types are:
-typedef Atomic<int> AtomicInt;
-typedef Atomic<unsigned int> AtomicUInt;
-typedef Atomic<__int64> AtomicInt64;
-typedef Atomic<unsigned __int64> AtomicUInt64;
-
-Fancier types include
-template <typename T> struct AtomicPtr;
-This is a pointer that has the same semantics as the above integer types
-
-template <typename T>struct AtomicPtrWithCount;
-
-AtomicPtrWithCount<T> is a very important type.  It has 32 bits of pointer
-and 32 bits of counter.  There are a number of algorithms that are possible
-when a pointer and a counter can be changed atomically together including a
-lock free pushdown stack and reference counted garbage collection where
-multiple processors can share pointers as well as sharing the data that's
-pointed at.
-
-template <typename T> struct AtomicPtrWithMark;
-
-This is similar to AtomicPtrWithCount<T> but the extra 32 bits are accessed
-as individual bits instead of being accessed as a counter.  It's not as
-important.  I was playing with algorithms before I realized that the
-important ones I was afraid of using had been published independently of my
-former employer.
-
-
-
-The atomic number types act as integer variables, but all changes to these
-variable happen through interlocked atomic instructions.
-All changes are therefor "globally visible" in Intel's parlance.
-
-Note that incrementing (or decrementing or adding to) one of these uses
-InterlockedExchangeAdd, which for 64 bit numbers ends up relying on "lock
-CMPXCHG8B"
-
-There's an Exchange method.
-
-There are also special methods that use compare exchange in some forms that
-I've found useful:
-
-T CompareExchange(T exchange, T comperand)
-bool SetIfEqual(T exchange, T comperand)
-
-and fancier ones I found some uses for
-
- inline bool SetIfSomeBitsAreEqual(T exchange, T comperand, T bitsToCompare)
- inline bool SetSomeBitsIfThoseBitsAreEqual(T exchange, 
-                                             T comperand, 
-                                             T bitsToCompare)
- inline bool SetSomeBitsIfSomeOtherBitsAreEqual(T exchange,
-              T bitsToExchange,
-              T comperand,
-              T bitsToCompare
-              )
-
- inline T CompareSomeBitsAndExchange(T exchange, 
-                                     T comperand, 
-                                     T bitsToCompare)
- inline T CompareSomeBitsAndExchangeThoseBits(T exchange, 
-                                             T comperand, 
-                                             T bitsToCompare)
- inline T CompareSomeBitsAndExchangeSomeOtherBits(T exchange,
-              T bitsToExchange,
-              T comperand,
-              T bitsToCompare
-              )
-
-There are also atomic bit test, bit test and set etc. methods:
-
- inline bool BTS(int bit)
- inline bool BTC(int bit)
- inline bool BTR(int bit)
- inline bool BT(int bit)
-
-ALGORITHMS and their classes:
-
-The important ones are:
-
-struct Counted
-Use this as the base type for any object you want to be reference counted
-
-template <typename T> class CountedPtr;
-Safely acts as pointer to a reference counted type.  This pointer can not be
-shared between threads safely.
-
-template <typename T> class AtomicCountedPtr;
-Like CountedPtr<T> but this pointer CAN be shared between threads/processors
-safely.
-
-template <typename T> class MPQueue;
-Multiprocessor queue.  This is the nonblocking shared FIFO.
-
-Note, for the sake of convenience there is a Fifo that has the same
-semantics but can only be used single threaded:
-template <typename T> class Queue ;
-
-class MPCountStack;
-This is the multiprocessor nonblocking LIFO stack.  Note that what gets
-pushed on the stack are pointers to MPStackElement. Your data must be
-objects derived from MPStackElements.  Note that it is not legal to push a
-NULL onto the stack - NULL is used to signal an empty stack.
-
-Note that for the sake of convienience there is, once again, a single
-threaded version of the stack:
-class SimpleStack.
-
-There are also classes for allocators that use the MPCountStack as a
-freelist.
-template <typename T, typename BLOCK_ALLOCATOR>
-struct MPCountFreeListAllocator;
-
-This template is recursive in the sense that each allocator gets new blocks
-from a shared allocatorn passed in the constructor (of type
-BLOCK_ALLOCATOR).  You can build a tree of allocators this way.  The root of
-the tree should be of type SimpleAllocator<T> which just calls new and
-delete.
-
-Once again, for the sake of simplicity, there is a single threaded version
-of the block allocator called
-template <typename T, typename BLOCK_ALLOCATOR> struct SimpleBlockAllocator
-
-*/
-#ifndef ATOMIC_H
-#define ATOMIC_H
-#include <windows.h>
-#include <assert.h>
-#include <new>
-using namespace std;
-/* 
-    windows defines the following interlocked routines
-    we need to define the equivalent for volatiles (which 
-    they should have been in the first place, and the following 
-    types voltatile long, volatile int, volatile unsigned long, 
-    volatile unsigned int,  volatile T*, volatile __int64, 
-    volatile unsigned __int64.
-
-    Note: I use the platform SDK which has different header files 
-    for interlocked instructions than the Windows includes in Visual 
-    C
-
-    If you have the platform SDK and the code doesn't compile then
-    you need to make sure that 
-    "C:\Program Files\Microsoft Platform SDK\include"
-    is the first directory listed under menus "Tools" -> menu item
-    "Options" -> tab "Directories" (of course if you installed the 
-    platform SDK in a different directory than 
-    "C:\Program Files\Microsoft Platform SDK" then you should use 
-    YOUR path.
-
-    If you don't have the plaform SDK then InterlockedCompareExchange 
-    is defined for void * instead of being defined for longs...  and 
-    there is no InterlockedCompareExchangePointer
-
-    The whole point of Microsoft having different headers was an update
-    to support 64 bit platforms which doesn't matter here at all (some 
-    of the code here relies on CMPXCHG8B swaping out both a pointer AND
-    a counter - a trick that won't work on the current 64 bit platforms).
-
-    In any case, if you don't have the platform SDK then just 
-    appropriate casts to make the code compile.  Keep in mind that 
-    casting from 64 bit types to 32 bit types is wrong - where there's 
-    a 64 bit type I meant it to call one of my assembly language
-    routines that uses CMPXCHG8B.
-
-    LONG
-    InterlockedIncrement(
-    LPLONG lpAddend
-    );
-
-    LONG
-    InterlockedDecrement(
-    LPLONG lpAddend
-    );
-
-    LONG
-    InterlockedExchange(
-    LPLONG Target,
-    LONG Value
-    );
-
-    LONG
-    InterlockedExchangeAdd(
-    LPLONG Addend,
-    LONG Value
-    );
-
-    LONG
-    InterlockedCompareExchange (
-    PLONG Destination,
-    LONG ExChange,
-    LONG Comperand
-    );
-
-    PVOID
-    InterlockedExchangePointer (
-    PVOID *Target,
-    PVOID Value
-    );
-
-    PVOID
-    InterlockedCompareExchangePointer (
-    PVOID *Destination,
-    PVOID ExChange,
-    PVOID Comperand
-    );
-*/
-
-//we'll need a special cases for volatile __int64 and 
-//volatile unsigned __int64
-
-template <typename T>
-inline T InterlockedIncrement(volatile T * ptr)
-{
-    return (T)InterlockedIncrement((LPLONG)ptr);
-}
-
-template <typename T>
-inline T InterlockedDecrement(volatile T * ptr)
-{
-    return (T)InterlockedDecrement((LPLONG)ptr);
-}
-
-template <typename T>
-inline T InterlockedExchange(volatile T * target,T value)
-{
-    return (T)InterlockedExchange((LPLONG)target,(LONG)value);
-}
-
-template <typename T>
-inline T InterlockedExchangeAdd(volatile T *addend,T value)
-{
-    return (T)InterlockedExchangeAdd((LPLONG)addend,(LONG)value);
-}
-
-template <typename T>
-T InterlockedCompareExchange (volatile T * dest,T exchange,T comperand)
-{
-    return (T)InterlockedCompareExchange ((LPLONG)dest,
-                                        (LONG)exchange,
-                                        (LONG)comperand);
-}
-//most common use of InterlockedCompareExchange
-template <typename T>
-bool InterlockedSetIfEqual (volatile T * dest,T exchange,T comperand)
-{
-    return comperand==InterlockedCompareExchange(dest,exchange,comperand);
-}
-
-//disable the no return value warning, because the assembly language
-//routines load the appropriate registers directly
-#pragma warning(disable:4035)
-
-inline unsigned __int64 
-InterlockedCompareExchange(volatile unsigned __int64 *dest
-                           ,unsigned __int64 exchange
-                           ,unsigned __int64 comperand) 
-{
-    //value returned in eax::edx
-    __asm {
-        lea esi,comperand;
-        lea edi,exchange;
-        
-        mov eax,[esi];
-        mov edx,4[esi];
-        mov ebx,[edi];
-        mov ecx,4[edi];
-        mov esi,dest;
-        //lock CMPXCHG8B [esi] is equivalent to the following except
-        //that it's atomic:
-        //ZeroFlag = (edx:eax == *esi);
-        //if (ZeroFlag) *esi = ecx:ebx;
-        //else edx:eax = *esi;
-        lock CMPXCHG8B [esi];			
-    }
-}
-
-//most common use of InterlockedCompareExchange
-//It's more efficient to use the z flag than to do another compare
-inline bool 
-InterlockedSetIfEqual(volatile unsigned __int64 *dest
-                      ,unsigned __int64 exchange
-                      ,unsigned __int64 comperand) 
-{
-    //value returned in eax
-    __asm {
-        lea esi,comperand;
-        lea edi,exchange;
-        
-        mov eax,[esi];
-        mov edx,4[esi];
-        mov ebx,[edi];
-        mov ecx,4[edi];
-        mov esi,dest;
-        //lock CMPXCHG8B [esi] is equivalent to the following except
-        //that it's atomic:
-        //ZeroFlag = (edx:eax == *esi);
-        //if (ZeroFlag) *esi = ecx:ebx;
-        //else edx:eax = *esi;
-        lock CMPXCHG8B [esi];			
-        mov eax,0;
-        setz al;
-    }
-}
-#pragma warning(default:4035)
-
-inline unsigned __int64 InterlockedIncrement(volatile unsigned __int64 * ptr)
-{
-    unsigned __int64 comperand;
-    unsigned __int64 exchange;
-    do {
-        comperand = *ptr;
-        exchange = comperand+1;
-    }while(!InterlockedSetIfEqual(ptr,exchange,comperand));
-    return exchange;
-}
-
-inline unsigned __int64 InterlockedDecrement(volatile unsigned __int64 * ptr)
-{
-    unsigned __int64 comperand;
-    unsigned __int64 exchange;
-    do {
-        comperand = *ptr;
-        exchange = comperand-1;
-    }while(!InterlockedSetIfEqual(ptr,exchange,comperand));
-    return exchange;
-}
-
-inline unsigned __int64 InterlockedExchange(volatile unsigned __int64 * target,
-                                            unsigned __int64 value)
-{
-    unsigned __int64 comperand;
-    do {
-        comperand = *target;
-    }while(!InterlockedSetIfEqual(target,value,comperand));
-    return comperand;
-}
-
-inline unsigned __int64 InterlockedExchangeAdd(volatile unsigned __int64 *addend,
-                                               unsigned __int64 value)
-{
-    unsigned __int64 comperand;
-    do {
-        comperand = *addend;
-    }while(!InterlockedSetIfEqual(addend,comperand+value,comperand));
-    return comperand;
-}
-
-#pragma warning(disable:4035)
-inline __int64 
-InterlockedCompareExchange(volatile __int64 *dest
-                           ,__int64 exchange
-                           ,__int64 comperand) 
-{
-    //value returned in eax::edx
-    __asm {
-        lea esi,comperand;
-        lea edi,exchange;
-        
-        mov eax,[esi];
-        mov edx,4[esi];
-        mov ebx,[edi];
-        mov ecx,4[edi];
-        mov esi,dest;
-        //lock CMPXCHG8B [esi] is equivalent to the following except
-        //that it's atomic:
-        //ZeroFlag = (edx:eax == *esi);
-        //if (ZeroFlag) *esi = ecx:ebx;
-        //else edx:eax = *esi;
-        lock CMPXCHG8B [esi];			
-    }
-}
-
-//most common use of InterlockedCompareExchange
-//It's more efficient to use the z flag than to do another compare
-inline bool 
-InterlockedSetIfEqual(volatile __int64 *dest
-                      ,__int64 exchange
-                      ,__int64 comperand) 
-{
-    //value returned in eax
-    __asm {
-        lea esi,comperand;
-        lea edi,exchange;
-        
-        mov eax,[esi];
-        mov edx,4[esi];
-        mov ebx,[edi];
-        mov ecx,4[edi];
-        mov esi,dest;
-        //lock CMPXCHG8B [esi] is equivalent to the following except
-        //that it's atomic:
-        //ZeroFlag = (edx:eax == *esi);
-        //if (ZeroFlag) *esi = ecx:ebx;
-        //else edx:eax = *esi;
-        lock CMPXCHG8B [esi];			
-        mov eax,0;
-        setz al;
-    }
-}
-#pragma warning(default:4035)
-
-inline __int64 InterlockedIncrement(volatile __int64 * dest)
-{
-    __int64 comperand;
-    __int64 exchange;
-    do {
-        comperand = *dest;
-        exchange = comperand+1;
-    }while(!InterlockedSetIfEqual(dest,exchange,comperand));
-    return exchange;
-}
-
-inline __int64 InterlockedDecrement(volatile __int64 * dest)
-{
-    __int64 comperand;
-    __int64 exchange;
-    do {
-        comperand = *dest;
-        exchange = comperand-1;
-    }while(!InterlockedSetIfEqual(dest,exchange,comperand));
-    return exchange;
-}
-
-inline __int64 InterlockedExchange(volatile __int64 * target,__int64 value)
-{
-    __int64 comperand;
-    do {
-        comperand = *target;
-    }while(!InterlockedSetIfEqual(target,value,comperand));
-    return comperand;
-}
-
-inline __int64 InterlockedExchangeAdd(volatile __int64 *addend,
-                                      __int64 value)
-{
-    __int64 comperand;
-    do {
-        comperand = *addend;
-    }while(!InterlockedSetIfEqual(addend,comperand+value,comperand));
-    return comperand;
-}
-
-#pragma warning(disable:4035)
-//I've just thought of some algorithms that use BTS and all so I'm including them
-inline bool InterlockedBTS(volatile int *dest, int bit)
-{
-    //value returned in eax
-    __asm{
-        mov eax,bit;
-        mov ebx,dest;
-        lock bts [ebx],eax;
-        mov eax,0;
-        setc al;
-    }
-}
-inline bool InterlockedBTC(volatile int *dest, int bit)
-{
-    //value returned in eax
-    __asm{
-        mov eax,bit;
-        mov ebx,dest;
-        lock btc [ebx],eax;
-        mov eax,0;
-        setc al;
-    }
-}
-inline bool InterlockedBTR(volatile int *dest, int bit)
-{
-    //value returned in eax
-    __asm{
-        mov eax,bit;
-        mov ebx,dest;
-        lock btr [ebx],eax;
-        mov eax,0;
-        setc al;
-    }
-}
-//you can lock BT but since it doesn't change memory there isn't really any point
-inline bool BT(volatile int *dest, int bit)
-{
-    //value returned in eax
-    __asm{
-        mov eax,bit;
-        mov ebx,dest;
-        bt [ebx],eax;
-        mov eax,0;
-        setc al;
-    }
-}
-#pragma warning(default:4035)
-
-inline bool InterlockedBTS(volatile unsigned *dest, int bit)
-{
-    return InterlockedBTS((volatile int *)dest,bit);
-}
-inline bool InterlockedBTC(volatile unsigned *dest, int bit)
-{
-    return InterlockedBTC((volatile int *)dest,bit);
-}
-inline bool InterlockedBTR(volatile unsigned *dest, int bit)
-{
-    return InterlockedBTR((volatile int *)dest,bit);
-}
-inline bool BT(volatile unsigned *dest, int bit)
-{
-    return BT((volatile int *)dest,bit);
-}
-
-inline bool InterlockedBTS(volatile unsigned long *dest, int bit)
-{
-    return InterlockedBTS((volatile int *)dest,bit);
-}
-inline bool InterlockedBTC(volatile unsigned long *dest, int bit)
-{
-    return InterlockedBTC((volatile int *)dest,bit);
-}
-inline bool InterlockedBTR(volatile unsigned long *dest, int bit)
-{
-    return InterlockedBTR((volatile int *)dest,bit);
-}
-inline bool BT(volatile unsigned long *dest, int bit)
-{
-    return BT((volatile int *)dest,bit);
-}
-
-inline bool InterlockedBTS(volatile long *dest, int bit)
-{
-    return InterlockedBTS((volatile int *)dest,bit);
-}
-inline bool InterlockedBTC(volatile long *dest, int bit)
-{
-    return InterlockedBTC((volatile int *)dest,bit);
-}
-inline bool InterlockedBTR(volatile long *dest, int bit)
-{
-    return InterlockedBTR((volatile int *)dest,bit);
-}
-inline bool BT(volatile long *dest, int bit)
-{
-    return BT((volatile int *)dest,bit);
-}
-
-inline bool InterlockedBTS(volatile __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTS((volatile int *)&dest,bit);
-    return InterlockedBTS(1+(volatile int *)&dest,bit-32);
-}
-inline bool InterlockedBTC(volatile __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTC((volatile int *)&dest,bit);
-    return InterlockedBTC(1+(volatile int *)&dest,bit-32);
-}
-inline bool InterlockedBTR(volatile __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTR((volatile int *)&dest,bit);
-    return InterlockedBTR(1+(volatile int *)&dest,bit-32);
-}
-inline bool BT(volatile __int64 *dest, int bit)
-{
-    if (bit<32) return BT((volatile int *)&dest,bit);
-    return BT(1+(volatile int *)&dest,bit-32);
-}
-inline bool InterlockedBTS(volatile unsigned __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTS((volatile int *)&dest,bit);
-    return InterlockedBTS(1+(volatile int *)&dest,bit-32);
-}
-inline bool InterlockedBTC(volatile unsigned __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTC((volatile int *)&dest,bit);
-    return InterlockedBTC(1+(volatile int *)&dest,bit-32);
-}
-inline bool InterlockedBTR(volatile unsigned __int64 *dest, int bit)
-{
-    if (bit<32) return InterlockedBTR((volatile int *)&dest,bit);
-    return InterlockedBTR(1+(volatile int *)&dest,bit-32);
-}
-inline bool BT(volatile unsigned __int64 *dest, int bit)
-{
-    if (bit<32) return BT((volatile int *)&dest,bit);
-    return BT(1+(volatile int *)&dest,bit-32);
-}
-
-//T can be int, unsigned int, long, unsigned long
-//__int64 or unsigned __int64
-template <typename T>
-struct Atomic 
-{
-    volatile T value;
-    
-    inline Atomic(){}
-    
-    explicit inline Atomic(T n)
-    { //so that it's globally visible (to use intel's terminology)
-        InterlockedExchange(&value,n);
-    }
-    
-    //if you need an atomic load then use (*this += 0)
-    //but I haven't found any algorithms that
-    //require an atomic load
-    inline operator T() const
-    {
-        return value;
-    }
-    
-    inline T CompareExchange(T exchange, T comperand)
-    {
-        return InterlockedCompareExchange(&value,exchange,comperand);
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare
-    inline T CompareSomeBitsAndExchange(T exchange, T comperand, T bitsToCompare)
-    {
-        T returned;
-        T bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return returned;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and in the set
-    inline T CompareSomeBitsAndExchangeThoseBits(T exchange, T comperand, T bitsToCompare)
-    {
-        T returned = comperand;
-        T bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            exchange = (exchange&bitsToCompare) | (bitsToIgnore&returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return returned;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and others in the set
-    inline T CompareSomeBitsAndExchangeSomeOtherBits(T exchange, 
-        T bitsToExchange,
-        T comperand, 
-        T bitsToCompare
-        )
-    {
-        T returned = value;
-        T bitsToIgnore = ~bitsToCompare;
-        T bitsToLeave = ~bitsToExchange;
-        for (;;){
-            exchange = (exchange&bitsToExchange) | (bitsToLeave&returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return returned;
-    }
-    
-    inline T Exchange(T exchange) 
-    {
-        return InterlockedExchange(&value,exchange);
-    }
-    
-    inline bool SetIfEqual(T exchange, T comperand)
-    {
-        return InterlockedSetIfEqual(&value,exchange,comperand);
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare
-    inline bool SetIfSomeBitsAreEqual(T exchange, T comperand, T bitsToCompare)
-    {
-        T returned;
-        T bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return false;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and in the set
-    inline bool SetSomeBitsIfThoseBitsAreEqual(T exchange, T comperand, T bitsToCompare)
-    {
-        T returned = comperand;
-        T bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            exchange = (exchange&bitsToCompare) | (bitsToIgnore&returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comperand = (comperand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return false;
-    }
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and others in the set
-    inline bool SetSomeBitsIfSomeOtherBitsAreEqual(T exchange, 
-        T bitsToExchange,
-        T comperand, 
-        T bitsToCompare
-        )
-    {
-        T returned = value;
-        T bitsToIgnore = ~bitsToCompare;
-        T bitsToLeave = ~bitsToExchange;
-        for (;;){
-            exchange = (exchange&bitsToExchange) | (bitsToLeave&returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comperand = (comperand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return false;
-    }
-    
-    inline T operator =(T exchange)
-    {
-        Exchange(exchange);
-        return exchange;
-    }
-    
-    inline T operator +=(T n)
-    {
-        return n + InterlockedExchangeAdd(&value, n);
-    }
-    
-    inline T operator -=(T n)
-    {
-        return InterlockedExchangeAdd(&value, -n) - n;
-    }
-    inline T operator ++()
-    {
-        return (*this += 1);
-    }
-    
-    inline T operator --() 
-    {
-        return (*this -= 1);
-    }
-    
-    inline T operator ++(int)
-    {
-        return InterlockedExchangeAdd(&value, (T)1);
-    }
-    
-    inline T operator --(int)
-    {
-        return InterlockedExchangeAdd(&value, (T)-1);
-    }
-    
-    inline T operator &=(T n)
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value; 
-            exchange = comperand & n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    inline T operator |= (T n) 
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value; 
-            exchange = comperand | n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    //yes this isn't standard, but it's useful
-    inline T Mask(T bitsToKeep, T bitsToSet) 
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value ; 
-            exchange = ((comperand & bitsToKeep) | bitsToSet);
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    inline T operator ^= (T n)
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value;  
-            exchange = comperand ^ n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    inline T operator *= (T n) 
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value;  
-            exchange = comperand * n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    inline T operator /= (T n) 
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value;
-            exchange = comperand / n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    inline T operator >>= (unsigned n) 
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value;
-            exchange = comperand >> n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    inline T operator <<= (unsigned n)
-    {
-        T comperand;
-        T exchange;
-        do {
-            comperand = value;
-            exchange = comperand << n;
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    inline bool BTS(int bit)
-    {
-        return InterlockedBTS(&value,bit);
-    }
-    inline bool BTC(int bit)
-    {
-        return InterlockedBTC(&value,bit);
-    }
-    inline bool BTR(int bit)
-    {
-        return InterlockedBTR(&value,bit);
-    }
-    inline bool BT(int bit)
-    {
-        return BT(&value,bit);
-    }
-}; 
-
-template <typename T>
-T * InterlockedCompareExchangePointer (
-                                       T *volatile *dest,
-                                       T * exchange,
-                                       T * comperand
-                                       )
-{
-    return (T*)InterlockedCompareExchangePointer((PVOID *)dest,(PVOID)exchange,(PVOID)comperand);
-}
-
-template <typename T>
-struct AtomicPtr 
-{
-    T * volatile value;
-    
-    inline AtomicPtr(){}
-    
-    explicit inline AtomicPtr(T *n)
-    { //so that it's globally visible (to use intel's terminology)
-        InterlockedExchange(&value,n);
-    }
-    explicit inline AtomicPtr(const T *n)
-    { //so that it's globally visible (to use intel's terminology)
-        InterlockedExchange(&value,(T *)n);
-    }
-    
-    inline operator T *() const
-    {
-        return value;
-    }
-    
-    inline operator const T *() const
-    {
-        return value;
-    }
-    
-    inline T *CompareExchange(T *exchange, T *comperand)
-    {
-        return InterlockedCompareExchangePointer(&value,exchange,comperand);
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare
-    inline T * CompareSomeBitsAndExchange(T * exchange, T * comperand, int bitsToCompare)
-    {
-        T  *returned;
-        int bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            returned = InterlockedCompareExchangePointer(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return returned;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and in the set
-    inline T * CompareSomeBitsAndExchangeThoseBits(T * exchange, T * comperand, int bitsToCompare)
-    {
-        T *returned = comperand;
-        int bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            exchange = (T*)((int)exchange&bitsToCompare) | (bitsToIgnore&(int)returned);
-            returned = InterlockedCompareExchangePointer(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (T*)((int)comparand&bitsToCompare) | (bitsToIgnore&(int)returned);
-        }
-        return returned;
-    }
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and others in the set
-    inline T* CompareSomeBitsAndExchangeSomeOtherBits(T *exchange, 
-        int bitsToExchange,
-        T * comperand, 
-        int bitsToCompare
-        )
-    {
-        T * returned = value;
-        int bitsToIgnore = ~bitsToCompare;
-        int bitsToLeave = ~bitsToExchange;
-        for (;;){
-            exchange = (T*)((int)exchange&bitsToExchange) | (bitsToLeave&(int)returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return returned;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (T*)((int)comparand&bitsToCompare) | (bitsToIgnore&(int)returned);
-        }
-        return returned;
-    }
-    
-    inline T * operator ->() const
-    {
-        assert (value != NULL);
-        return value;
-    }
-    
-    inline T *Exchange(T *exchange) 
-    {
-        return InterlockedExchange(&value,exchange);
-    }
-    
-    inline bool SetIfEqual(T *exchange, T *comperand)
-    {
-        return comperand==InterlockedCompareExchangePointer(&value,exchange,comperand);
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare
-    inline bool SetIfSomeBitsAreEqual(T * exchange, T * comperand, int bitsToCompare)
-    {
-        T  *returned;
-        int bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            returned = InterlockedCompareExchangePointer(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (comparand&bitsToCompare) | (bitsToIgnore&returned);
-        }
-        return false;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and in the set
-    inline bool SetSomeBitsIfThoseBitsAreEqual(T * exchange, T * comperand, int bitsToCompare)
-    {
-        T *returned = comperand;
-        int bitsToIgnore = ~bitsToCompare;
-        for (;;){
-            exchange = (T*)((int)exchange&bitsToCompare) | (bitsToIgnore&(int)returned);
-            returned = InterlockedCompareExchangePointer(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (T*)((int)comparand&bitsToCompare) | (bitsToIgnore&(int)returned);
-        }
-        return false;
-    }
-    
-    //useful - simulates having a compareexchange that ignores some bits in
-    //the compare and others in the set
-    inline bool SetSomeBitsIfSomeOtherBitsAreEqual(T *exchange, 
-        int bitsToExchange,
-        T * comperand, 
-        int bitsToCompare
-        )
-    {
-        T * returned = value;
-        int bitsToIgnore = ~bitsToCompare;
-        int bitsToLeave = ~bitsToExchange;
-        for (;;){
-            exchange = (T*)((int)exchange&bitsToExchange) | (bitsToLeave&(int)returned);
-            returned = InterlockedCompareExchange(&value,exchange,comperand);
-            if (returned == comperand) return true;
-            if (0 != ((returned ^ comperand) & bitsToCompare)) break;
-            comparand = (T*)((int)comparand&bitsToCompare) | (bitsToIgnore&(int)returned);
-        }
-        return false;
-    }
-    
-    inline T *operator =(T *exchange)
-    {
-        Exchange(exchange);
-        return exchange;
-    }
-    
-    template <typename INT_TYPE>
-        inline T *operator +=(INT_TYPE n)
-    {
-        return n + (T *)InterlockedExchangeAdd((LPLONG)&value, (LONG)(n * (LONG)sizeof(T)));
-    }
-    
-    template <typename INT_TYPE>
-        inline T *operator -=(INT_TYPE n)
-    {
-        return (T *)InterlockedExchangeAdd((LPLONG)&value, (LONG)(-n * (LONG)sizeof(T))) - n;
-    }
-    inline T *operator ++()
-    {
-        return (T *)InterlockedExchangeAdd((LPLONG)&value, (LONG)(sizeof(T))) + 1;
-    }
-    
-    inline T *operator --() 
-    {
-        return (T *)InterlockedExchangeAdd((LPLONG)&value, -(LONG)(sizeof(T))) - 1;
-    }
-    
-    inline T *operator ++(int)
-    {
-        return (T*)InterlockedExchangeAdd((LPLONG)&value, (LONG)sizeof(T));
-    }
-    
-    inline T *operator --(int)
-    {
-        return (T*)InterlockedExchangeAdd((LPLONG)&value, -(LONG)sizeof(T));
-    }
-    
-    //yes this isn't standard, but it's useful
-    template <typename INT_TYPE>
-        inline T *operator &=(INT_TYPE n)
-    {
-        T * comperand;
-        T * exchange;
-        do {
-            comperand = value; 
-            exchange = (T *)((LONG)comperand & n);
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    //yes this isn't standard, but it's useful
-    template <typename INT_TYPE>
-        inline T *operator |= (INT_TYPE n) 
-    {
-        T * comperand;
-        T * exchange;
-        do {
-            comperand = value; 
-            exchange = (T *)((LONG)comperand | n);
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    //yes this isn't standard, but it's useful
-    template <typename INT_TYPE>
-        inline T operator ^= (INT_TYPE n)
-    {
-        T * comperand;
-        T * exchange;
-        do {
-            comperand = value;  
-            exchange = (T *)((LONG)comperand ^ n);
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    //yes this isn't standard, but it's useful
-    template <typename INT_TYPE_A, typename INT_TYPE_B>
-        inline T * Mask(INT_TYPE_A bitsToKeep, INT_TYPE_B bitsToSet) 
-    {
-        T * comperand;
-        T * exchange;
-        do {
-            comperand = value ; 
-            exchange = (T *)(((LONG)comperand & bitsToKeep) | bitsToSet);
-        }while(!SetIfEqual(exchange, comperand));
-        return exchange;
-    }
-    
-    
-    inline bool BTS(int bit)
-    {
-        return InterlockedBTS((volatile int *)&value,bit);
-    }
-    inline bool BTC(int bit)
-    {
-        return InterlockedBTC((volatile int *)&value,bit);
-    }
-    inline bool BTR(int bit)
-    {
-        return InterlockedBTR((volatile int *)&value,bit);
-    }
-    inline bool BT(int bit)
-    {
-        return BT((volatile int *)&value,bit);
-    }
-};
-
-typedef Atomic<int> AtomicInt;
-typedef Atomic<unsigned int> AtomicUInt;
-typedef Atomic<__int64> AtomicInt64;
-typedef Atomic<unsigned __int64> AtomicUInt64;
-
-template
-<typename T, typename A = AtomicUInt64>
-struct AtomicUnion
-{
-    A whole;
-    
-    AtomicUnion()
-    {
-        assert(sizeof(T)<=sizeof(A));
-        new((void *)&whole) T();//in place new
-        
-    }
-    
-    ~AtomicUnion()
-    {
-        ((T *)&whole)->~T();
-    }
-    
-    T &Value() 
-    {
-        return *(T *)&whole;
-    }
-    const T &Value() const
-    {
-        return *(const T *)&whole;
-    }
-};
-
-
-template <typename T>
-struct AtomicPtrWithCountStruct
-{
-    AtomicPtr<T> ptr;
-    AtomicInt count;
-};
-
-
-template <typename T>
-struct PtrWithCountStruct
-{
-    T* ptr;
-    int count;
-};
-
-template <typename T, int MARKBITS=3>
-struct BitMarkedAtomicPtr : public AtomicPtr<T>
-{
-    const int MarkMask() const
-    {
-        return (1<<MARKBITS)-1;
-    }
-    
-    const int DataMask() const
-    {
-        return ~ThreadBitMask();
-    }
-    
-    static T * MaskPtr(T *data)
-    {
-        return (T*)((int)data & DataMask());
-    }
-    
-    static int MaskMark(T * data)
-    {
-        return ((int)data & MarkMask());
-    }
-    
-    static T* Mark(T * data, int bit)
-    {
-        return (T*)((int)data | 1<<bit);
-    }
-    
-    static T* Unmark(T * data, int bit)
-    {
-        return (T*)((int)data & ~(1<<bit));
-    }
-    
-    T * MaskPtr()
-    {
-        return MaskPtr(value);
-    }
-    
-    int MaskMark()
-    {
-        return MaskMark(value);
-    }
-    
-    //note new value has the marks in exchange not the original marks
-    inline bool SetIfMarked(T *exchange, int bit)
-    {
-        assert(bit<MARKBITS);
-        return SetIfSomeBitsAreEqual(exchange,DataMask(),(T*)(1<<bit),1<<bit);
-    }
-    
-    //note new value has the marks in exchange not the original marks
-    T * ExchangeIfMarked(T *exchange, int bit)
-    {
-        assert(bit<MARKBITS);
-        return CompareSomeBitsAndExchange(exchange,DataMask(),(T*)(1<<bit),1<<bit);
-    }
-    
-    inline bool SetAndClearMarksIfMarked(T *exchange, int bit)
-    {
-        return SetIfMarked(MaskPtr(exchange),bit);
-    }
-    
-    inline T * ExchangeAndClearMarksIfMarked(T *exchange, int bit)
-    {
-        return ExchangeIfMarked(MaskPtr(exchange),bit);
-    }
-    
-    inline bool SetAndClearOtherMarksIfMarked(T *exchange, int bit)
-    {
-        return SetIfMarked(Mark(MaskPtr(exchange),bit),
-            bit);
-    }
-    
-    //note new value has the marks in exchange not the original marks
-    T * ExchangeAndClearOtherMarksIfMarked(T *exchange, int bit)
-    {
-        return ExchangeIfMarked(Mark(MaskPtr(exchange),bit),
-            bit);
-    }
-    
-    inline bool SetAndMarkIfMarked(T *exchange, int bit)
-    {
-        return SetSomeBitsIfSomeOtherBitsAreEqual(
-            Mark(MaskPtr(exchange),bit),
-            DataMask() | 1<<bit,
-            (T*)(1<<bit),
-            1<<bit);
-    }
-    
-    inline T * ExchangeAndMarkIfMarked(T *exchange, int bit)
-    {
-        return CompareSomeBitsAndExchangeSomeOtherBits(
-            Mark(MaskPtr(exchange),bit),
-            DataMask() | 1<<bit,
-            (T*)(1<<bit),
-            1<<bit);
-    }	 
-    
-    bool Mark(int bit)
-    {
-        assert(bit<MARKBITS);
-        return BTS(bit);
-    }
-    
-    bool Unmark(int bit)
-    {
-        assert(bit<MARKBITS);
-        return BTC(bit);
-    }
-    
-    bool InvertMark(int bit)
-    {
-        assert(bit<MARKBITS);
-        return BTR(bit);
-    }
-    
-    bool IsMarked(int bit)
-    {
-        assert(bit<MARKBITS);
-        return BT(bit);
-    }
-};
-
-template <typename T>
-struct AtomicPtrWithCount : public AtomicUnion< AtomicPtrWithCountStruct<T> >
-{
-    typedef AtomicUnion< PtrWithCountStruct<T>, unsigned __int64 > SimpleUnionType;
-    AtomicPtrWithCount()
-    {
-        whole = 0;
-    }
-    AtomicPtrWithCount(unsigned __int64 o)
-    {
-        whole = o.whole;
-    }
-    AtomicPtrWithCount(T *ptr)
-    {
-        SimpleUnionType o;
-        o.Value().ptr = ptr;
-        o.Value().count = 0;
-        whole = o.whole;
-    }
-    
-    operator unsigned __int64() const
-    {
-        return whole;
-    }
-    T *Ptr() const
-    {
-        return Value().ptr;
-    }
-    int Count() const
-    {
-        return Value().count;
-    }
-    unsigned __int64 Whole() const
-    {
-        return whole;
-    }
-    
-    AtomicPtr<T> & Ptr()
-    {
-        return Value().ptr;
-    }
-    AtomicInt & Count()
-    {
-        return Value().count;
-    }
-    AtomicUInt64 & Whole()
-    {
-        return whole;
-    }
-    unsigned __int64 SetPtrAndIncCount(T *ptr)
-    {
-        SimpleUnionType was;
-        SimpleUnionType to;
-        to.Value().ptr = ptr;
-        do {
-            was.whole = whole;
-            to.Value().count = was.Value().count+1;
-        }while(!whole.SetIfEqual(to.whole,was.whole));
-        return to.whole;
-    }
-    bool SetIfPtrEqualAndIncCount(T *exchange, T *comperand)
-    {
-        SimpleUnionType was;
-        SimpleUnionType to;
-        to.ptr = exchange;
-        do {
-            was.whole = whole;
-            if (was.Value().ptr != comperand) return false;
-            to.Value().count = was.Value().count+1;
-        }while(!whole.SetIfEqual(to.whole,was.whole));
-        return true;
-    }
-    unsigned __int64 ExchangeIfPtrEqualAndIncCount(T *exchange, T *comperand)
-    {
-        SimpleUnionType was;
-        SimpleUnionType to;
-        to.ptr = exchange;
-        do {
-            was.whole = whole;
-            if (was.Value().ptr != comperand) return was.whole;
-            to.Value().count = was.Value().count+1;
-        }while(!whole.SetIfEqual(to.whole,was.whole));
-        return was.whole;
-    }
-    inline T *operator =(T *exchange)
-    {
-        SetPtrAndIncCount(exchange);
-        return exchange;
-    }
-    
-    template <typename INT_TYPE>
-        inline T *operator +=(INT_TYPE n)
-    {
-        T *was;
-        T *to;
-        do {
-            was = Ptr();
-            to = was + n;
-        }while (!SetIfPtrEqualAndIncCount(to,was));
-        return to;
-    }
-    
-    template <typename INT_TYPE>
-        inline T *operator -=(INT_TYPE n)
-    {
-        T *was;
-        T *to;
-        do {
-            was = Ptr();
-            to = was - n;
-        }while (!SetIfPtrEqualAndIncCount(to,was));
-        return to;
-    }
-    inline T *operator ++()
-    {
-        return (*this += 1);
-    }
-    
-    inline T *operator --() 
-    {
-        return (*this -= 1);
-    }
-    
-    inline T *operator ++(int)
-    {
-        return (++ *this) - 1;
-    }
-    
-    inline T *operator --(int)
-    {
-        return (-- *this) + 1;
-    }
-};
-
-template <typename T>
-struct AtomicPtrWithMarkStruct
-{
-    AtomicPtr<T> ptr;
-    AtomicUInt mark;
-};
-
-
-template <typename T>
-struct PtrWithMarkStruct
-{
-    T* ptr;
-    unsigned int mark;
-};
-
-template <typename T>
-struct AtomicPtrWithMark : public AtomicUnion< AtomicPtrWithMarkStruct<T> >
-{
-    typedef AtomicUnion< PtrWithMarkStruct<T>, unsigned __int64 > SimpleUnionType;
-    AtomicPtrWithMark()
-    {
-        whole = 0;
-    }
-    AtomicPtrWithMark(unsigned __int64 o)
-    {
-        whole = o.whole;
-    }
-    AtomicPtrWithMark(T *ptr)
-    {
-        SimpleUnionType o;
-        o.Value().ptr = ptr;
-        o.Value().mark = 0;
-        whole = o.whole;
-    }
-    
-    operator unsigned __int64() const
-    {
-        return whole;
-    }
-    T *Ptr() const
-    {
-        return Value().ptr;
-    }
-    int Mark() const
-    {
-        return Value().mark;
-    }
-    unsigned __int64 Whole() const
-    {
-        return whole;
-    }
-    
-    AtomicPtr<T> & Ptr()
-    {
-        return Value().ptr;
-    }
-    AtomicInt & Mark()
-    {
-        return Value().mark;
-    }
-    AtomicUInt64 & Whole()
-    {
-        return whole;
-    }
-    
-    inline bool SetAndClearOtherMarksIfMarked(T *exchange, int bit)
-    {
-        assert(bit<32);
-        SimpleUnionType compareMask;
-        compareMask.Value().ptr = NULL;
-        compareMask.Value().mark = 1u<<bit;
-        
-        SimpleUnionType exchangeValue;
-        exchangeValue.Value().ptr = exchange;
-        exchangeValue.Value().mark = compareMask.Value().mark;
-        
-        return whole.SetSomeBitsIfSomeOtherBitsAreEqual(exchangeValue.whole,
-            (unsigned __int64)-1i64,
-            compareMask.whole,
-            compareMask.whole);
-    }
-    inline bool SetAndClearMarksIfPtrEqual(T *exchange, T*comparend)
-    {
-        SimpleUnionType compareMask;
-        compareMask.Value().ptr = (T*)-1;
-        compareMask.Value().mark = 0;
-        
-        SimpleUnionType compareValue;
-        compareValue.Value().ptr = comparend;
-        compareValue.Value().mark = 0;
-        
-        SimpleUnionType exchangeValue;
-        exchangeValue.Value().ptr = exchange;
-        exchangeValue.Value().mark = 0;
-        
-        return whole.SetSomeBitsIfThoseBitsAreEqual(exchangeValue.whole,
-            compareValue.whole,
-            compareMask.whole);
-    }
-    
-    inline bool SetAndClearMarksIfMarked(T *exchange, int bit)
-    {
-        assert(bit<32);
-        SimpleUnionType compareMask;
-        compareMask.Value().ptr = NULL;
-        compareMask.Value().mark = 1u<<bit;
-        
-        SimpleUnionType exchangeValue;
-        exchangeValue.Value().ptr = exchange;
-        exchangeValue.Value().mark = 0;
-        
-        return whole.SetSomeBitsIfSomeOtherBitsAreEqual(exchangeValue.whole,
-            (unsigned __int64)-1i64,
-            compareMask.whole,
-            compareMask.whole);
-    }
-    //note new value has the marks in exchange not the original marks
-    unsigned __int64 ExchangeAndClearOtherMarksIfMarked(T *exchange, int bit)
-    {
-        assert(bit<32);
-        SimpleUnionType compareMask;
-        compareMask.Value().ptr = NULL;
-        compareMask.Value().mark = 1u<<bit;
-        
-        SimpleUnionType exchangeValue;
-        exchangeValue.Value().ptr = exchange;
-        exchangeValue.Value().mark = compareMask.Value().mark;
-        
-        return whole.CompareSomeBitsAndExchangeSomeOtherBits(exchangeValue.whole,
-            exchangeMask.whole,
-            compareMask.whole,
-            compareMask.whole);
-    }
-    
-    unsigned __int64 ExchangeAndClearMarksIfMarked(T *exchange, int bit)
-    {
-        assert(bit<32);
-        SimpleUnionType compareMask;
-        compareMask.Value().ptr = NULL;
-        compareMask.Value().mark = 1u<<bit;
-        
-        SimpleUnionType exchangeValue;
-        exchangeValue.Value().ptr = exchange;
-        exchangeValue.Value().mark = 0;
-        
-        return whole.CompareSomeBitsAndExchangeSomeOtherBits(exchangeValue.whole,
-            exchangeMask.whole,
-            compareMask.whole,
-            compareMask.whole);
-    }
-    
-    
-    bool Mark(int bit)
-    {
-        assert(bit<32);
-        return whole.BTS(bit);
-    }
-    
-    bool Unmark(int bit)
-    {
-        assert(bit<32);
-        return whole.BTC(bit);
-    }
-    
-    bool InvertMark(int bit)
-    {
-        assert(bit<32);
-        return whole.BTR(bit);
-    }
-    
-    bool IsMarked(int bit)
-    {
-        assert(bit<32);
-        return whole.BT(bit);
-    }
-};
-
-struct MPStackElement
-{
-    MPStackElement * next;
-};
-
-class MPMarkStack
-{
-protected:
-    AtomicPtrWithMark<MPStackElement> tos;
-    AtomicUInt availableThreadBits;
-    AtomicInt lastReserved;
-    
-public:
-    
-    MPStackElement* ExchangeStack(MPStackElement *newStack = NULL)
-    {
-        AtomicPtrWithMark<MPStackElement>::SimpleUnionType newWhole, ret;
-        newWhole.Value().mark = 0;
-        newWhole.Value().ptr = newStack;
-        ret.whole = tos.whole.Exchange(newWhole.whole);
-        return ret.Value().ptr;
-    }
-    
-    MPMarkStack()
-    {
-        lastReserved = 0;
-        tos.whole = 0;
-        availableThreadBits = (unsigned)-1;
-    }
-    
-    //expensive - call once per thread to reserve a bit
-    int ReserveThreadBit()
-    {
-        int offset = lastReserved;
-        //since locked operations are slow we only do
-        //bit tests on bits that look acceptable because
-        //of a nonlocked read.
-        unsigned readOnce = availableThreadBits;
-        for (int i=0; i< 32;++i){
-            const int bit = (31&(i+offset));
-            const unsigned mask = 1u<<bit;
-            if ((readOnce & mask)!=0){
-                if (availableThreadBits.BTR(bit)) {
-                    lastReserved = ((bit+1)&31);//try the next one
-                    return bit+1;
-                }
-                readOnce = availableThreadBits;
-            }
-        }
-        return 0;
-    }
-    int BlockingReserveThreadBit()
-    {
-        int i;
-        while (0==(i=ReserveThreadBit()));
-        return i;
-    }
-    int ReturnThreadBit(int i)
-    {
-        availableThreadBits.BTS(i-1);
-    }
-    
-    void PushElement(MPStackElement *element)
-    {
-        MPStackElement * next;
-        do {
-            next = tos.Value().ptr;
-            element->next = tos.Value().ptr;
-        }while(!tos.SetAndClearMarksIfPtrEqual(element,next));
-    }
-    
-    void PushList(MPStackElement *top, MPStackElement *bottom)
-    {
-        MPStackElement * next;
-        do {
-            next = tos.Value().ptr;
-            bottom->next = tos.Value().ptr;
-        }while(!tos.SetAndClearMarksIfPtrEqual(top,next));
-    }
-    
-    MPStackElement* PopElement(int i)
-    {
-        for(;;) {
-            tos.Value().mark.BTS(i-1);
-            MPStackElement * was = tos.Value().ptr;
-            if (was == NULL) return NULL;
-            if (tos.SetAndClearMarksIfMarked(was->next,i-1)) return was;
-        }
-    }
-    MPStackElement* PopElement()
-    {
-        int id = BlockingReserveThreadBit();
-        MPStackElement * ret = PopElement(id);
-        ReturnThreadBit(id);
-        return ret;
-    }
-};
-class MPCountStack
-{
-protected:
-    AtomicPtrWithCount<MPStackElement> tos;
-    
-public:
-    
-    MPStackElement* ExchangeStack(MPStackElement *newStack = NULL)
-    {
-        return tos.Value().ptr.Exchange(newStack);
-    }
-    
-    MPCountStack()
-    {
-        tos = 0;
-    }
-    
-    
-    void PushElement(MPStackElement *element)
-    {
-        MPStackElement * next;
-        do {
-            next = tos.Value().ptr;
-            element->next = tos.Value().ptr;
-        }while(!tos.Value().ptr.SetIfEqual(element,next));
-    }
-    
-    void PushList(MPStackElement *top, MPStackElement *bottom)
-    {
-        MPStackElement * next;
-        do {
-            next = tos.Value().ptr;
-            bottom->next = tos.Value().ptr;
-        }while(!tos.Value().ptr.SetIfEqual(top,next));
-    }
-    
-    MPStackElement* PopElement()
-    {
-        AtomicPtrWithCount<MPStackElement>::SimpleUnionType was;
-        AtomicPtrWithCount<MPStackElement>::SimpleUnionType to;
-        do {
-            was.whole = tos.whole;
-            if (was.Value().ptr == NULL) return NULL;
-            to.Value().count = was.Value().count + 1;
-            to.Value().ptr = was.Value().ptr->next;
-        }while(!tos.whole.SetIfEqual(was.whole,to.whole));
-        return was.Value().ptr;
-    }
-};
-
-class SimpleStack
-{
-protected:
-    MPStackElement * tos;
-    
-public:
-    
-    MPStackElement* ExchangeStack(MPStackElement *newStack = NULL)
-    {
-        MPStackElement* was = tos;
-        tos = newStack;
-        return was;
-    }
-    
-    SimpleStack()
-    {
-        tos = 0;
-    }
-    
-    
-    void PushElement(MPStackElement *element)
-    {
-        element->next = tos;
-        tos = element;
-    }
-    
-    void PushList(MPStackElement *top, MPStackElement *bottom)
-    {
-        bottom->next = tos;
-        tos = top;
-    }
-    
-    MPStackElement* PopElement()
-    {
-        MPStackElement* was = tos;
-        if (was) tos = was->next;
-        return was;
-    }
-};
-
-template <typename T>
-struct MPMemBlock : public MPStackElement
-{
-    T data;
-    char bottomOfBlock;
-};
-
-#define OFFSET_OF_MEMBER(type,member) ((int)&(((type *)0)->member))
-
-//put one of these in each thread object 
-//and you have thread local allocation
-template <typename T, typename BLOCK_ALLOCATOR>
-struct SimpleBlockAllocator
-{
-    SimpleStack data;
-    
-    typedef SimpleBlockAllocator<T,BLOCK_ALLOCATOR> AllocatorType;
-    
-    BLOCK_ALLOCATOR & MyAllocator;
-    
-    SimpleBlockAllocator(BLOCK_ALLOCATOR &source)
-        :MyAllocator(source)
-    {}
-    
-    int ReserveThreadBit(){return 1;}
-    int BlockingReserveThreadBit(){return 1;}
-    void ReturnThreadBit(int){  }
-    
-    int Size() const { return sizeof(T); }
-    void AddBlock()
-    {
-        int blockSize = MyAllocator.Size();
-        int elementSize = sizeof(MPMemBlock<T>);
-        assert( MyAllocator.Size() >= elementSize);
-        MPMemBlock<T> *bottom = (MPMemBlock<T> *)MyAllocator.Allocate();
-        void *prev = 0;
-        MPMemBlock<T> *top = bottom;  
-        do {
-            top->bottomOfBlock = 0;
-            top->next = prev;
-            prev = (void *)top;
-            ++top;
-        }while( (blockSize-=elementSize) >= elementSize);
-        bottom->bottomOfBlock = 1;
-        data.PushList(top-1,bottom);
-    }
-    void *Allocate(int) 
-    {	
-        return Allocate();
-    }
-    void *Allocate() 
-    {	
-        MPMemBlock<T> *ret;
-        for(;;) {
-            ret = (MPMemBlock<T> *)data.PopElement();
-            if (ret!=NULL) return &ret->data;
-            AddBlock();
-        }
-    }
-    void Deallocate(void *ob) 
-    {
-        if (!ob) return;
-        MPMemBlock<T> *ret = (MPMemBlock<T> *)
-            ((char *)data - OFFSET_OF_MEMBER(MPMemBlock<T>,ob));
-        data.PushElement(ret);
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    void Clear() 
-    {
-        MPMemBlock<T> *stackWas = (MPMemBlock<T> *)data.ExchangeStack(NULL);
-        MPMemBlock<T> *blocks = NULL;
-        while(stackWas){
-            if (stackWas->bottomOfBlock){
-                if (blocks) {
-                    blocks->next = stackWas;
-                }
-                blocks = stackWas;
-            }
-            stackWas = (MPMemBlock<T> *)(stackWas->next);
-        }
-        while(blocks)
-        {
-            stackWas = (MPMemBlock<T> *)blocks->next;
-            MyAllocator.Deallocate(blocks);
-            blocks = stackWas;
-        }
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    ~SimpleBlockAllocator()
-    {
-        Clear();
-    }
-};
-
-template<class T>
-struct SimpleAllocator
-{
-    void *Allocate() { return (void *)new char[sizeof(T)]; }
-    void *Allocate(int) { return Allocate(); }
-    
-    int ReserveThreadBit(){return 1;}
-    int BlockingReserveThreadBit(){return 1;}
-    void ReturnThreadBit(int){}
-    
-    void Deallocate(void *data) { delete[] (char[])data; }
-    int Size() const { return sizeof(T); }
-    typedef SimpleAllocator AllocatorType;
-};
-
-enum DontReserve{ DONT_RESERVE };
-
-template<class T>
-struct ThreadMarkedAllocator
-{
-    T& allocator;
-    int bit;
-    
-    ThreadMarkedAllocator(T &sourceAllocator)
-        :allocator(sourceAllocator)
-        ,bit(sourceAllocator.BlockingReserveThreadBit())
-    {}
-    
-    ThreadMarkedAllocator(T &sourceAllocator,DontReserve)
-        :allocator(sourceAllocator)
-        ,bit(0)
-    {}
-    
-    ~ThreadMarkedAllocator()
-    {
-        allocator.ReturnThreadBit(bit);
-    }
-    
-    bool ReserveThreadBit()
-    {
-        if (bit==0) bit=sourceAllocator.ReserveThreadBit();
-        return bit!=0;
-    }
-    void BlockingReserveThreadBit()
-    {
-        if (bit==0) bit=sourceAllocator.BlockingReserveThreadBit();
-    }
-    void ReturnThreadBit()
-    {
-        int was = bit;
-        bit = 0;
-        sourceAllocator.ReturnThreadBit(was);
-    }
-    
-    void *Allocate() 
-    { 
-        assert(bit!=0);
-        return allocator.Allocate(bit); 
-    }
-    
-    void Deallocate(void *data) { allocator.Deallocate(data); }
-    int Size() const { return Allocator.Size(); }
-    typedef ThreadMarkedAllocator<T> AllocatorType;
-};
-
-template <typename T, typename BLOCK_ALLOCATOR>
-struct MPMarkFreeListAllocator
-{
-    MPMarkStack data;
-    
-    typedef MPMarkFreeListAllocator<T,BLOCK_ALLOCATOR> AllocatorType;
-    
-    BLOCK_ALLOCATOR &MyAllocator;
-    
-    MPMarkFreeListAllocator(BLOCK_ALLOCATOR &source)
-        :MyAllocator(source)
-    {}
-    
-    int ReserveThreadBit(){return data.ReserveThreadBit();}
-    int BlockingReserveThreadBit(){return data.BlockingReserveThreadBit();}
-    void ReturnThreadBit(int bit){ data.ReturnThreadBit(bit); }
-    
-    int Size() const { return sizeof(T); }
-    void AddBlock()
-    {
-        int blockSize = MyAllocator.Size();
-        int elementSize = sizeof(MPMemBlock<T>);
-        assert( MyAllocator.Size() >= elementSize);
-        MPMemBlock<T> *bottom = (MPMemBlock<T> *)MyAllocator.Allocate();
-        void *prev = 0;
-        MPMemBlock<T> *top = bottom;  
-        do {
-            top->bottomOfBlock = 0;
-            top->next = prev;
-            prev = (void *)top;
-            ++top;
-        }while( (blockSize-=elementSize) >= elementSize);
-        bottom->bottomOfBlock = 1;
-        data.PushList(top-1,bottom);
-    }
-    void *Allocate(int mark) 
-    {	
-        MPMemBlock<T> *ret;
-        for(;;) {
-            ret = (MPMemBlock<T> *)data.PopElement(mark);
-            if (ret!=NULL) return ret;
-            AddBlock();
-        }
-    }
-    void *Allocate() 
-    {	
-        MPMemBlock<T> *ret;
-        for(;;) {
-            ret = (MPMemBlock<T> *)data.PopElement();
-            if (ret!=NULL) return &ret->data;
-            AddBlock();
-        }
-    }
-    void Deallocate(void *ob) 
-    {
-        if (!ob) return;
-        MPMemBlock<T> *ret = (MPMemBlock<T> *)
-            ((char *)data - OFFSET_OF_MEMBER(MPMemBlock<T>,ob));
-        data.PushElement(ret);
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    void Clear()
-    {
-        MPMemBlock<T> *stackWas = (MPMemBlock<T> *)data.ExchangeStack(NULL);
-        MPMemBlock<T> *blocks = NULL;
-        while(stackWas){
-            if (stackWas->bottomOfBlock){
-                if (blocks) {
-                    blocks->next = stackWas;
-                }
-                blocks = stackWas;
-            }
-            stackWas = (MPMemBlock<T> *)(stackWas->next);
-        }
-        while(blocks)
-        {
-            stackWas = (MPMemBlock<T> *)blocks->next;
-            MyAllocator.Deallocate(blocks);
-            blocks = stackWas;
-        }
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    ~MPMarkFreeListAllocator()
-    {
-        Clear();
-    }
-};
-template <typename T, typename BLOCK_ALLOCATOR>
-struct MPCountFreeListAllocator
-{
-    MPCountStack data;
-    
-    typedef MPCountFreeListAllocator<T,BLOCK_ALLOCATOR> AllocatorType;
-    
-    BLOCK_ALLOCATOR & MyAllocator;
-    
-    MPCountFreeListAllocator(BLOCK_ALLOCATOR &source)
-        :MyAllocator(source)
-    {}
-    
-    int ReserveThreadBit(){return 1;}
-    int BlockingReserveThreadBit(){return 1;}
-    void ReturnThreadBit(int){  }
-    
-    int Size() const { return sizeof(T); }
-    void AddBlock()
-    {
-        int blockSize = MyAllocator.Size();
-        int elementSize = sizeof(MPMemBlock<T>);
-        assert( MyAllocator.Size() >= elementSize);
-        MPMemBlock<T> *bottom = (MPMemBlock<T> *)MyAllocator.Allocate();
-        void *prev = 0;
-        MPMemBlock<T> *top = bottom;  
-        do {
-            top->bottomOfBlock = 0;
-            top->next = prev;
-            prev = (void *)top;
-            ++top;
-        }while( (blockSize-=elementSize) >= elementSize);
-        bottom->bottomOfBlock = 1;
-        data.PushList(top-1,bottom);
-    }
-    void *Allocate(int) 
-    {	
-        return Allocate();
-    }
-    void *Allocate() 
-    {	
-        MPMemBlock<T> *ret;
-        for(;;) {
-            ret = (MPMemBlock<T> *)data.PopElement();
-            if (ret!=NULL) return &ret->data;
-            AddBlock();
-        }
-    }
-    void Deallocate(void *ob) 
-    {
-        if (!ob) return;
-        MPMemBlock<T> *ret = (MPMemBlock<T> *)
-            ((char *)data - OFFSET_OF_MEMBER(MPMemBlock<T>,ob));
-        data.PushElement(ret);
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    void Clear() 
-    {
-        MPMemBlock<T> *stackWas = (MPMemBlock<T> *)data.ExchangeStack(NULL);
-        MPMemBlock<T> *blocks = NULL;
-        while(stackWas){
-            if (stackWas->bottomOfBlock){
-                if (blocks) {
-                    blocks->next = stackWas;
-                }
-                blocks = stackWas;
-            }
-            stackWas = (MPMemBlock<T> *)(stackWas->next);
-        }
-        while(blocks)
-        {
-            stackWas = (MPMemBlock<T> *)blocks->next;
-            MyAllocator.Deallocate(blocks);
-            blocks = stackWas;
-        }
-    }
-    //all memory allocated must be Deallocated before Clear() or the destructor is called
-    ~MPCountFreeListAllocator()
-    {
-        Clear();
-    }
-};
-
-struct Counted
-{
-    mutable AtomicInt refCount;
-    Counted():refCount(0){}
-};
-
-//it is NOT safe to read or write from more than one thread at a time
-template <typename T> 
-class CountedPtr
-{
-    
-protected:
-    T *value;
-    void decRefCount()
-    {
-        decRefCount(value);
-    }
-public:
-    static void decRefCount(T *ptr)
-    {
-        if (ptr && 0 == --ptr->refCount){
-            delete ptr;
-        }
-    }
-    void SetValueIgnoringRefCounts(T *ptr) 
-    { 
-        value = ptr; 
-    }
-    CountedPtr():letter(NULL){}
-    
-    CountedPtr(T *ptr)
-    {
-        value = ptr;
-        if (value) ++value->refCount;
-    }
-    
-    operator const T *() const { return value; }
-    operator T *() { return value; }
-    
-    CountedPtr<T> & operator=(const T *ptr)
-    {
-        if (ptr) ++ptr->refCount;
-        decRefCount();
-        value = ptr;
-        return *this;
-    }
-    
-    operator bool() const
-    { return value!=NULL; }
-    
-    bool operator !() const
-    { return value==NULL; }
-    
-    
-    const T & operator*() const
-    { return *value; }
-    
-    T & operator*()
-    { return *value; }
-    
-    T * operator->()
-    { assert(value); return value; }
-    const T * operator->()const
-    { assert(value); return value; }
-    
-    ~CountedPtr()
-    {
-        decRefCount();
-    }
-};
-
-template <typename T>
-class AtomicCountedPtr
-{
-protected:
-    mutable AtomicPtrWithCount<T> value;
-public:
-    
-    
-    CountedPtr<T> & LoadValue(CountedPtr<T> &dest) const 
-    { 
-retry:
-    AtomicPtrWithCount<T>::SimpleUnionType inc;
-    inc.Value().ptr = 0;
-    inc.Value().count = 1;
-    AtomicPtrWithCount<T>::SimpleUnionType ret;
-    ret.whole = (value.whole+=inc.whole); //increment in ptr
-    dest = ret.Value().ptr ; //increment in object
-    AtomicPtrWithCount<T>::SimpleUnionType update;
-    update.Value().ptr = ret.Value().ptr;
-    for(;;){
-        update.Value().count = ret.Value().count-1;
-        AtomicPtrWithCount<T>::SimpleUnionType current;
-        current.whole = value.whole.SetIfEqual(update.whole,ret.whole);
-        if (current.whole == ret.whole) break; //successfully decremented in ptr
-        if (current.Value().ptr != ret.Value().ptr) || current.Value().count < 1){
-            //because of the line "dest = ret.Value().ptr" above
-            //the old value will decrement in the prev object as the next object is loaded
-            goto retry; 
-        }
-        ret.Value().count = current.Value().count;
-    }
-    return dest; 
-    }
-    
-    CountedPtr<T> & LoadValue(CountedPtr<T> &dest, int &count) const 
-    { 
-retry:
-    AtomicPtrWithCount<T>::SimpleUnionType inc;
-    inc.Value().ptr = 0;
-    inc.Value().count = 1;
-    AtomicPtrWithCount<T>::SimpleUnionType ret;
-    ret.whole = (value.whole+=inc.whole); //increment in ptr
-    dest = ret.Value().ptr ; //increment in object
-    AtomicPtrWithCount<T>::SimpleUnionType update;
-    update.Value().ptr = ret.Value().ptr;
-    for(;;){
-        update.Value().count = ret.Value().count-1;
-        AtomicPtrWithCount<T>::SimpleUnionType current;
-        current.whole = value.whole.SetIfEqual(update.whole,ret.whole);
-        if (current.whole == ret.whole) break; //successfully decremented in ptr
-        if (current.Value().ptr != ret.Value().ptr) || current.Value().count < 1){
-            //because of the line "dest = ret.Value().ptr" above
-            //the old value will decrement in the prev object as the next object is loaded
-            goto retry; 
-        }
-        ret.Value().count = current.Value().count;
-    }
-    count = ret.Value().count;
-    return dest; 
-    }
-    
-    CountedPtr<T> & ExchangeInPlace(CountedPtr<T> &dest)
-    { 
-        AtomicPtrWithCount<T>::SimpleUnionType destWhole;
-        destWhole.Value().ptr = dest;
-        destWhole.Value().count = 0;
-        destWhole.whole = value.whole.Exchange(destWhole.whole);
-        if (destWhole.Value().ptr != NULL && destWhole.Value().count != 0) 
-            destWhole.Value().ptr->refCount += destWhole.Value().count;
-        dest.SetValueIgnoringRefCounts(destWhole.Value().ptr);
-        return dest; 
-    }
-    
-    CountedPtr<T> & Exchange(CountedPtr<T> &dest, T *source)
-    { 
-        dest = source;
-        return ExchangeInPlace(dest);
-    }
-    
-    bool CompareExchange(CountedPtr<T> &dest, T *exchange, T * comparend)
-    { 
-        CountedPtr<T> holdExchange(exchange);
-retry:
-        AtomicPtrWithCount<T>::SimpleUnionType comp;
-        if (LoadValue(dest,comp.Value().count) != comparend) return false;
-        comp.Value().ptr = dest;
-        AtomicPtrWithCount<T>::SimpleUnionType exch;
-        exch.Value().ptr=exchange;
-        exch.Value().count = 0;
-        AtomicPtrWithCount<T>::SimpleUnionType ret;
-        for (;;){
-            ret.whole = value.whole.CompareExchange(exch.whole,comp.whole);
-            if (ret.whole == comp.whole) {
-                //transfer increment from holdExchange to this
-                holdExchange.SetValueIgnoringRefCounts(NULL);
-                //had inc from Load and the one from this 
-                if (dest) {
-                    const int dec = 1-comp.Value().count;
-                    if (dec!=0) dest->refCount -= dec;
-                }
-                return true;
-            }
-            if (ret.Value().ptr != comp.Value().ptr) {
-                //cant return the new pointer because there's no
-                //reason to think it hasn't been collected already
-                goto retry;
-            }
-            comp.Value().count = ret.Value().count;
-        }
-    }
-    
-    bool SetIfEqual(T *exchange, T * comparend)
-    { 
-        CountedPtr<T> holdExchange(exchange);
-retry:
-        AtomicPtrWithCount<T>::SimpleUnionType comp;
-        comp.whole = value.whole;
-        if (comp.Value().ptr != comparend) return false;
-        AtomicPtrWithCount<T>::SimpleUnionType exch;
-        exch.Value().ptr=exchange;
-        exch.Value().count = 0;
-        AtomicPtrWithCount<T>::SimpleUnionType ret;
-        for (;;){
-            ret.whole = value.whole.CompareExchange(exch.whole,comp.whole);
-            if (ret.whole == comp.whole) {
-                if (comp.Value().ptr) {
-                    const int dec = 1-comp.Value().count;
-                    if (dec!=0 && 0==(comp.Value().ptr->refCount -= dec)){
-                        delete comp.Value().ptr;
-                    };
-                }
-                //transfer increment from holdExchange to this
-                holdExchange.SetValueIgnoringRefCounts(NULL);
-                return true;
-            }
-            if (ret.Value().ptr != comp.Value().ptr) {
-                return false;
-            }
-            comp.Value().count = ret.Value().count;
-        }
-    }
-    
-    void operator = (const T *ptr)
-    {
-        CountedPtr<T> dest(ptr);
-        ExchangeInPlace(dest);
-    }
-    
-    //not recommended because value won't be consistant throughout 
-    //a given expression
-    operator bool() const
-    { return value.Value().ptr!=NULL; }
-    
-    //not recommended because value won't be consistant throughout 
-    //a given expression
-    bool operator !() const
-    { return value.Value().ptr==NULL; }
-    
-    
-    AtomicCountedPtr()
-    {}
-    
-    ~AtomicCountedPtr()
-    {
-        *this = (T*)NULL;
-    }
-};
-
-class MPQueueBase
-{
-    AtomicUInt * data;
-    int len;
-    
-    struct AtomicHeadAndTail{
-        AtomicInt head;
-        AtomicInt tail;
-    };
-    
-    AtomicUnion<AtomicHeadAndTail> headAndTail;
-    
-    struct HeadAndTailStruct{
-        int head;
-        int tail;
-    };
-    union HeadAndTailUnion
-    {
-        HeadAndTailStruct value;
-        unsigned __int64 whole;
-    };
-    
-    AtomicUInt & Index(int i)
-    {
-        return data[i & (len-1)];
-    }
-    bool IsNil(int i)
-    {
-        return (i & 1) != 0;
-    }
-    
-    public:
-        
-        int Used() const
-        {
-            HeadAndTailUnion ht;
-            ht.whole = headAndTail.whole;
-            return ht.value.head-ht.value.tail;
-            
-        }
-        bool Empty() const
-        {
-            HeadAndTailUnion ht;
-            ht.whole = headAndTail.whole;
-            return ht.value.head==ht.value.tail;
-        }
-        int Available() const
-        {
-            return MaxLen()-Used();
-            
-        }
-        int MaxLen() const
-        {
-            return len;
-        }
-        
-        MPQueueBase(int lenLn2)
-            :len(1<<lenLn2)
-        {
-            headAndTail.whole = 0;
-            data = new AtomicUInt[len];
-            for (int i=0;i<len;++i) data[i] = 1;
-        }
-        
-        ~MPQueueBase()
-        {
-            delete [] data;
-        }
-        
-        bool Put(int v)
-        {
-            assert((v&1)==0);
-            for(;;){
-                HeadAndTailUnion ht;
-                ht.whole = headAndTail.whole;
-                if (ht.value.head-ht.value.tail >= len) return false;
-                
-                int wasThere = Index(ht.value.head);
-                
-                if (IsNil(wasThere)){
-                    if (Index(ht.value.head).SetIfEqual(v,wasThere)){
-                        headAndTail.Value().head.SetIfEqual(1+ht.value.head,ht.value.head);
-                        return true;
-                    }
-                }
-                headAndTail.Value().head.SetIfEqual(1+ht.value.head,ht.value.head);
-            }
-        }
-        int Get()
-        {
-            for(;;){
-                HeadAndTailUnion ht;
-                ht.whole = headAndTail.whole;
-                if (ht.value.head-ht.value.tail < 1) return 0;
-                
-                int wasThere = Index(ht.value.tail);
-                int newNil = (ht.value.tail|1);
-                
-                if (!IsNil(wasThere)){
-                    if (Index(ht.value.tail).SetIfEqual(newNil,wasThere)){
-                        headAndTail.Value().tail.SetIfEqual(1+ht.value.tail,ht.value.tail);
-                        return wasThere;
-                    }
-                }
-                headAndTail.Value().tail.SetIfEqual(1+ht.value.tail,ht.value.tail);
-            }
-        }
-};
-
-template <typename T>
-class MPQueue 
-{
-    MPQueueBase queue;
-public:
-    MPQueue(int lenLn2)
-        :queue(lenLn2)
-    {}
-    T *Get()
-    {
-        return (T*)queue.Get();
-    }
-    bool Put(T * v)
-    {
-        return queue.Put((int)v);
-    }
-    bool Empty() const
-    {
-        return queue.Empty();
-    }
-    int Used() const
-    {
-        return queue.Used();
-        
-    }
-    int Available() const
-    {
-        return queue.Available();
-        
-    }
-    int MaxLen() const
-    {
-        return queue.MaxLen();
-    }
-};
-
-class QueueBase
-{
-    unsigned * data;
-    int len;
-    
-    int head;
-    int tail;
-    
-    unsigned & Index(int i)
-    {
-        return data[i & (len-1)];
-    }
-    
-public:
-    
-    int Used() const
-    {
-        return head-tail;
-        
-    }
-    bool Empty() const
-    {
-        return head==tail;
-        
-    }
-    
-    int Available() const
-    {
-        return MaxLen()-Used();
-        
-    }
-    int MaxLen() const
-    {
-        return len;
-    }
-    
-    QueueBase(int lenLn2)
-        :len(1<<lenLn2)
-        ,head(0)
-        ,tail(0)
-    {
-        data = new unsigned[len];
-        for (int i=0;i<len;++i) data[i] = 1;
-    }
-    
-    ~QueueBase()
-    {
-        delete [] data;
-    }
-    
-    bool Put(int v)
-    {
-        if (Available() < 1) return false;
-        Index(head++) = v;
-        return true;
-    }
-    
-    int Get()
-    {
-        if (Used() < 1) return 0;
-        return Index(tail++);
-    }
-};
-template <typename T>
-class Queue 
-{
-    QueueBase queue;
-public:
-    Queue(int lenLn2)
-        :queue(lenLn2)
-    {}
-    T *Get()
-    {
-        return (T*)queue.Get();
-    }
-    bool Put(T * v)
-    {
-        return queue.Put((int)v);
-    }
-    bool Empty() const
-    {
-        return queue.Empty();
-    }
-    int Used() const
-    {
-        return queue.Used();
-        
-    }
-    int Available() const
-    {
-        return queue.Available();
-        
-    }
-    int MaxLen() const
-    {
-        return queue.MaxLen();
-    }
-};
-
-
-#endif
diff --git a/lib/base/x11/keysym.nim b/lib/base/x11/keysym.nim
deleted file mode 100644
index 8958aabcb..000000000
--- a/lib/base/x11/keysym.nim
+++ /dev/null
@@ -1,1900 +0,0 @@
-#
-#Converted from X11/keysym.h and X11/keysymdef.h
-#
-#Capital letter consts renamed from XK_... to XKc_...
-# (since Pascal isn't case-sensitive)
-#
-#i.e.
-#C      Pascal
-#XK_a   XK_a
-#XK_A   XKc_A
-#
-
-#* default keysyms *
-
-const 
-  XK_VoidSymbol* = 0x00FFFFFF # void symbol 
-
-when defined(XK_MISCELLANY): 
-  #*
-  # * TTY Functions, cleverly chosen to map to ascii, for convenience of
-  # * programming, but could have been arbitrary (at the cost of lookup
-  # * tables in client code.
-  # *
-  XK_BackSpace == 0x0000FF08  # back space, back char 
-  XK_Tab == 0x0000FF09
-  XK_Linefeed == 0x0000FF0A   # Linefeed, LF 
-  XK_Clear == 0x0000FF0B
-  XK_Return == 0x0000FF0D     # Return, enter 
-  XK_Pause == 0x0000FF13      # Pause, hold 
-  XK_Scroll_Lock == 0x0000FF14
-  XK_Sys_Req == 0x0000FF15
-  XK_Escape == 0x0000FF1B
-  XK_Delete == 0x0000FFFF     # Delete, rubout 
-                              # International & multi-key character composition 
-  XK_Multi_key == 0x0000FF20  # Multi-key character compose 
-  XK_Codeinput == 0x0000FF37
-  XK_SingleCandidate == 0x0000FF3C
-  XK_MultipleCandidate == 0x0000FF3D
-  XK_PreviousCandidate == 0x0000FF3E # Japanese keyboard support 
-  XK_Kanji == 0x0000FF21      # Kanji, Kanji convert 
-  XK_Muhenkan == 0x0000FF22   # Cancel Conversion 
-  XK_Henkan_Mode == 0x0000FF23 # Start/Stop Conversion 
-  XK_Henkan == 0x0000FF23     # Alias for Henkan_Mode 
-  XK_Romaji == 0x0000FF24     # to Romaji 
-  XK_Hiragana == 0x0000FF25   # to Hiragana 
-  XK_Katakana == 0x0000FF26   # to Katakana 
-  XK_Hiragana_Katakana == 0x0000FF27 # Hiragana/Katakana toggle 
-  XK_Zenkaku == 0x0000FF28    # to Zenkaku 
-  XK_Hankaku == 0x0000FF29    # to Hankaku 
-  XK_Zenkaku_Hankaku == 0x0000FF2A # Zenkaku/Hankaku toggle 
-  XK_Touroku == 0x0000FF2B    # Add to Dictionary 
-  XK_Massyo == 0x0000FF2C     # Delete from Dictionary 
-  XK_Kana_Lock == 0x0000FF2D  # Kana Lock 
-  XK_Kana_Shift == 0x0000FF2E # Kana Shift 
-  XK_Eisu_Shift == 0x0000FF2F # Alphanumeric Shift 
-  XK_Eisu_toggle == 0x0000FF30 # Alphanumeric toggle 
-  XK_Kanji_Bangou == 0x0000FF37 # Codeinput 
-  XK_Zen_Koho == 0x0000FF3D   # Multiple/All Candidate(s) 
-  XK_Mae_Koho == 0x0000FF3E   # Previous Candidate 
-                              # = $FF31 thru = $FF3F are under XK_KOREAN 
-                              # Cursor control & motion 
-  XK_Home == 0x0000FF50
-  XK_Left == 0x0000FF51       # Move left, left arrow 
-  XK_Up == 0x0000FF52         # Move up, up arrow 
-  XK_Right == 0x0000FF53      # Move right, right arrow 
-  XK_Down == 0x0000FF54       # Move down, down arrow 
-  XK_Prior == 0x0000FF55      # Prior, previous 
-  XK_Page_Up == 0x0000FF55
-  XK_Next == 0x0000FF56       # Next 
-  XK_Page_Down == 0x0000FF56
-  XK_End == 0x0000FF57        # EOL 
-  XK_Begin == 0x0000FF58      # BOL 
-                              # Misc Functions 
-  XK_Select == 0x0000FF60     # Select, mark 
-  XK_Print == 0x0000FF61
-  XK_Execute == 0x0000FF62    # Execute, run, do 
-  XK_Insert == 0x0000FF63     # Insert, insert here 
-  XK_Undo == 0x0000FF65       # Undo, oops 
-  XK_Redo == 0x0000FF66       # redo, again 
-  XK_Menu == 0x0000FF67
-  XK_Find == 0x0000FF68       # Find, search 
-  XK_Cancel == 0x0000FF69     # Cancel, stop, abort, exit 
-  XK_Help == 0x0000FF6A       # Help 
-  XK_Break == 0x0000FF6B
-  XK_Mode_switch == 0x0000FF7E # Character set switch 
-  XK_script_switch == 0x0000FF7E # Alias for mode_switch 
-  XK_Num_Lock == 0x0000FF7F   # Keypad Functions, keypad numbers cleverly chosen to map to ascii 
-  XK_KP_Space == 0x0000FF80   # space 
-  XK_KP_Tab == 0x0000FF89
-  XK_KP_Enter == 0x0000FF8D   # enter 
-  XK_KP_F1 == 0x0000FF91      # PF1, KP_A, ... 
-  XK_KP_F2 == 0x0000FF92
-  XK_KP_F3 == 0x0000FF93
-  XK_KP_F4 == 0x0000FF94
-  XK_KP_Home == 0x0000FF95
-  XK_KP_Left == 0x0000FF96
-  XK_KP_Up == 0x0000FF97
-  XK_KP_Right == 0x0000FF98
-  XK_KP_Down == 0x0000FF99
-  XK_KP_Prior == 0x0000FF9A
-  XK_KP_Page_Up == 0x0000FF9A
-  XK_KP_Next == 0x0000FF9B
-  XK_KP_Page_Down == 0x0000FF9B
-  XK_KP_End == 0x0000FF9C
-  XK_KP_Begin == 0x0000FF9D
-  XK_KP_Insert == 0x0000FF9E
-  XK_KP_Delete == 0x0000FF9F
-  XK_KP_Equal == 0x0000FFBD   # equals 
-  XK_KP_Multiply == 0x0000FFAA
-  XK_KP_Add == 0x0000FFAB
-  XK_KP_Separator == 0x0000FFAC # separator, often comma 
-  XK_KP_Subtract == 0x0000FFAD
-  XK_KP_Decimal == 0x0000FFAE
-  XK_KP_Divide == 0x0000FFAF
-  XK_KP_0 == 0x0000FFB0
-  XK_KP_1 == 0x0000FFB1
-  XK_KP_2 == 0x0000FFB2
-  XK_KP_3 == 0x0000FFB3
-  XK_KP_4 == 0x0000FFB4
-  XK_KP_5 == 0x0000FFB5
-  XK_KP_6 == 0x0000FFB6
-  XK_KP_7 == 0x0000FFB7
-  XK_KP_8 == 0x0000FFB8
-  XK_KP_9 == 0x0000FFB9 #*
-                        # * Auxilliary Functions; note the duplicate definitions for left and right
-                        # * function keys;  Sun keyboards and a few other manufactures have such
-                        # * function key groups on the left and/or right sides of the keyboard.
-                        # * We've not found a keyboard with more than 35 function keys total.
-                        # *
-  XK_F1 == 0x0000FFBE
-  XK_F2 == 0x0000FFBF
-  XK_F3 == 0x0000FFC0
-  XK_F4 == 0x0000FFC1
-  XK_F5 == 0x0000FFC2
-  XK_F6 == 0x0000FFC3
-  XK_F7 == 0x0000FFC4
-  XK_F8 == 0x0000FFC5
-  XK_F9 == 0x0000FFC6
-  XK_F10 == 0x0000FFC7
-  XK_F11 == 0x0000FFC8
-  XK_L1 == 0x0000FFC8
-  XK_F12 == 0x0000FFC9
-  XK_L2 == 0x0000FFC9
-  XK_F13 == 0x0000FFCA
-  XK_L3 == 0x0000FFCA
-  XK_F14 == 0x0000FFCB
-  XK_L4 == 0x0000FFCB
-  XK_F15 == 0x0000FFCC
-  XK_L5 == 0x0000FFCC
-  XK_F16 == 0x0000FFCD
-  XK_L6 == 0x0000FFCD
-  XK_F17 == 0x0000FFCE
-  XK_L7 == 0x0000FFCE
-  XK_F18 == 0x0000FFCF
-  XK_L8 == 0x0000FFCF
-  XK_F19 == 0x0000FFD0
-  XK_L9 == 0x0000FFD0
-  XK_F20 == 0x0000FFD1
-  XK_L10 == 0x0000FFD1
-  XK_F21 == 0x0000FFD2
-  XK_R1 == 0x0000FFD2
-  XK_F22 == 0x0000FFD3
-  XK_R2 == 0x0000FFD3
-  XK_F23 == 0x0000FFD4
-  XK_R3 == 0x0000FFD4
-  XK_F24 == 0x0000FFD5
-  XK_R4 == 0x0000FFD5
-  XK_F25 == 0x0000FFD6
-  XK_R5 == 0x0000FFD6
-  XK_F26 == 0x0000FFD7
-  XK_R6 == 0x0000FFD7
-  XK_F27 == 0x0000FFD8
-  XK_R7 == 0x0000FFD8
-  XK_F28 == 0x0000FFD9
-  XK_R8 == 0x0000FFD9
-  XK_F29 == 0x0000FFDA
-  XK_R9 == 0x0000FFDA
-  XK_F30 == 0x0000FFDB
-  XK_R10 == 0x0000FFDB
-  XK_F31 == 0x0000FFDC
-  XK_R11 == 0x0000FFDC
-  XK_F32 == 0x0000FFDD
-  XK_R12 == 0x0000FFDD
-  XK_F33 == 0x0000FFDE
-  XK_R13 == 0x0000FFDE
-  XK_F34 == 0x0000FFDF
-  XK_R14 == 0x0000FFDF
-  XK_F35 == 0x0000FFE0
-  XK_R15 == 0x0000FFE0        # Modifiers 
-  XK_Shift_L == 0x0000FFE1    # Left shift 
-  XK_Shift_R == 0x0000FFE2    # Right shift 
-  XK_Control_L == 0x0000FFE3  # Left control 
-  XK_Control_R == 0x0000FFE4  # Right control 
-  XK_Caps_Lock == 0x0000FFE5  # Caps lock 
-  XK_Shift_Lock == 0x0000FFE6 # Shift lock 
-  XK_Meta_L == 0x0000FFE7     # Left meta 
-  XK_Meta_R == 0x0000FFE8     # Right meta 
-  XK_Alt_L == 0x0000FFE9      # Left alt 
-  XK_Alt_R == 0x0000FFEA      # Right alt 
-  XK_Super_L == 0x0000FFEB    # Left super 
-  XK_Super_R == 0x0000FFEC    # Right super 
-  XK_Hyper_L == 0x0000FFED    # Left hyper 
-  XK_Hyper_R == 0x0000FFEE    # Right hyper 
-# XK_MISCELLANY 
-#*
-# * ISO 9995 Function and Modifier Keys
-# * Byte 3 = = $FE
-# *
-
-when defined(XK_XKB_KEYS): 
-  XK_ISO_Lock == 0x0000FE01
-  XK_ISO_Level2_Latch == 0x0000FE02
-  XK_ISO_Level3_Shift == 0x0000FE03
-  XK_ISO_Level3_Latch == 0x0000FE04
-  XK_ISO_Level3_Lock == 0x0000FE05
-  XK_ISO_Group_Shift == 0x0000FF7E # Alias for mode_switch 
-  XK_ISO_Group_Latch == 0x0000FE06
-  XK_ISO_Group_Lock == 0x0000FE07
-  XK_ISO_Next_Group == 0x0000FE08
-  XK_ISO_Next_Group_Lock == 0x0000FE09
-  XK_ISO_Prev_Group == 0x0000FE0A
-  XK_ISO_Prev_Group_Lock == 0x0000FE0B
-  XK_ISO_First_Group == 0x0000FE0C
-  XK_ISO_First_Group_Lock == 0x0000FE0D
-  XK_ISO_Last_Group == 0x0000FE0E
-  XK_ISO_Last_Group_Lock == 0x0000FE0F
-  XK_ISO_Left_Tab == 0x0000FE20
-  XK_ISO_Move_Line_Up == 0x0000FE21
-  XK_ISO_Move_Line_Down == 0x0000FE22
-  XK_ISO_Partial_Line_Up == 0x0000FE23
-  XK_ISO_Partial_Line_Down == 0x0000FE24
-  XK_ISO_Partial_Space_Left == 0x0000FE25
-  XK_ISO_Partial_Space_Right == 0x0000FE26
-  XK_ISO_Set_Margin_Left == 0x0000FE27
-  XK_ISO_Set_Margin_Right == 0x0000FE28
-  XK_ISO_Release_Margin_Left == 0x0000FE29
-  XK_ISO_Release_Margin_Right == 0x0000FE2A
-  XK_ISO_Release_Both_Margins == 0x0000FE2B
-  XK_ISO_Fast_Cursor_Left == 0x0000FE2C
-  XK_ISO_Fast_Cursor_Right == 0x0000FE2D
-  XK_ISO_Fast_Cursor_Up == 0x0000FE2E
-  XK_ISO_Fast_Cursor_Down == 0x0000FE2F
-  XK_ISO_Continuous_Underline == 0x0000FE30
-  XK_ISO_Discontinuous_Underline == 0x0000FE31
-  XK_ISO_Emphasize == 0x0000FE32
-  XK_ISO_Center_Object == 0x0000FE33
-  XK_ISO_Enter == 0x0000FE34
-  XK_dead_grave == 0x0000FE50
-  XK_dead_acute == 0x0000FE51
-  XK_dead_circumflex == 0x0000FE52
-  XK_dead_tilde == 0x0000FE53
-  XK_dead_macron == 0x0000FE54
-  XK_dead_breve == 0x0000FE55
-  XK_dead_abovedot == 0x0000FE56
-  XK_dead_diaeresis == 0x0000FE57
-  XK_dead_abovering == 0x0000FE58
-  XK_dead_doubleacute == 0x0000FE59
-  XK_dead_caron == 0x0000FE5A
-  XK_dead_cedilla == 0x0000FE5B
-  XK_dead_ogonek == 0x0000FE5C
-  XK_dead_iota == 0x0000FE5D
-  XK_dead_voiced_sound == 0x0000FE5E
-  XK_dead_semivoiced_sound == 0x0000FE5F
-  XK_dead_belowdot == 0x0000FE60
-  XK_dead_hook == 0x0000FE61
-  XK_dead_horn == 0x0000FE62
-  XK_First_Virtual_Screen == 0x0000FED0
-  XK_Prev_Virtual_Screen == 0x0000FED1
-  XK_Next_Virtual_Screen == 0x0000FED2
-  XK_Last_Virtual_Screen == 0x0000FED4
-  XK_Terminate_Server == 0x0000FED5
-  XK_AccessX_Enable == 0x0000FE70
-  XK_AccessX_Feedback_Enable == 0x0000FE71
-  XK_RepeatKeys_Enable == 0x0000FE72
-  XK_SlowKeys_Enable == 0x0000FE73
-  XK_BounceKeys_Enable == 0x0000FE74
-  XK_StickyKeys_Enable == 0x0000FE75
-  XK_MouseKeys_Enable == 0x0000FE76
-  XK_MouseKeys_Accel_Enable == 0x0000FE77
-  XK_Overlay1_Enable == 0x0000FE78
-  XK_Overlay2_Enable == 0x0000FE79
-  XK_AudibleBell_Enable == 0x0000FE7A
-  XK_Pointer_Left == 0x0000FEE0
-  XK_Pointer_Right == 0x0000FEE1
-  XK_Pointer_Up == 0x0000FEE2
-  XK_Pointer_Down == 0x0000FEE3
-  XK_Pointer_UpLeft == 0x0000FEE4
-  XK_Pointer_UpRight == 0x0000FEE5
-  XK_Pointer_DownLeft == 0x0000FEE6
-  XK_Pointer_DownRight == 0x0000FEE7
-  XK_Pointer_Button_Dflt == 0x0000FEE8
-  XK_Pointer_Button1 == 0x0000FEE9
-  XK_Pointer_Button2 == 0x0000FEEA
-  XK_Pointer_Button3 == 0x0000FEEB
-  XK_Pointer_Button4 == 0x0000FEEC
-  XK_Pointer_Button5 == 0x0000FEED
-  XK_Pointer_DblClick_Dflt == 0x0000FEEE
-  XK_Pointer_DblClick1 == 0x0000FEEF
-  XK_Pointer_DblClick2 == 0x0000FEF0
-  XK_Pointer_DblClick3 == 0x0000FEF1
-  XK_Pointer_DblClick4 == 0x0000FEF2
-  XK_Pointer_DblClick5 == 0x0000FEF3
-  XK_Pointer_Drag_Dflt == 0x0000FEF4
-  XK_Pointer_Drag1 == 0x0000FEF5
-  XK_Pointer_Drag2 == 0x0000FEF6
-  XK_Pointer_Drag3 == 0x0000FEF7
-  XK_Pointer_Drag4 == 0x0000FEF8
-  XK_Pointer_Drag5 == 0x0000FEFD
-  XK_Pointer_EnableKeys == 0x0000FEF9
-  XK_Pointer_Accelerate == 0x0000FEFA
-  XK_Pointer_DfltBtnNext == 0x0000FEFB
-  XK_Pointer_DfltBtnPrev == 0x0000FEFC
-#*
-# * 3270 Terminal Keys
-# * Byte 3 = = $FD
-# *
-
-when defined(XK_3270): 
-  XK_3270_Duplicate == 0x0000FD01
-  XK_3270_FieldMark == 0x0000FD02
-  XK_3270_Right2 == 0x0000FD03
-  XK_3270_Left2 == 0x0000FD04
-  XK_3270_BackTab == 0x0000FD05
-  XK_3270_EraseEOF == 0x0000FD06
-  XK_3270_EraseInput == 0x0000FD07
-  XK_3270_Reset == 0x0000FD08
-  XK_3270_Quit == 0x0000FD09
-  XK_3270_PA1 == 0x0000FD0A
-  XK_3270_PA2 == 0x0000FD0B
-  XK_3270_PA3 == 0x0000FD0C
-  XK_3270_Test == 0x0000FD0D
-  XK_3270_Attn == 0x0000FD0E
-  XK_3270_CursorBlink == 0x0000FD0F
-  XK_3270_AltCursor == 0x0000FD10
-  XK_3270_KeyClick == 0x0000FD11
-  XK_3270_Jump == 0x0000FD12
-  XK_3270_Ident == 0x0000FD13
-  XK_3270_Rule == 0x0000FD14
-  XK_3270_Copy == 0x0000FD15
-  XK_3270_Play == 0x0000FD16
-  XK_3270_Setup == 0x0000FD17
-  XK_3270_Record == 0x0000FD18
-  XK_3270_ChangeScreen == 0x0000FD19
-  XK_3270_DeleteWord == 0x0000FD1A
-  XK_3270_ExSelect == 0x0000FD1B
-  XK_3270_CursorSelect == 0x0000FD1C
-  XK_3270_PrintScreen == 0x0000FD1D
-  XK_3270_Enter == 0x0000FD1E
-#*
-# *  Latin 1
-# *  Byte 3 = 0
-# *
-
-when defined(XK_LATIN1): 
-  XK_space == 0x00000020
-  XK_exclam == 0x00000021
-  XK_quotedbl == 0x00000022
-  XK_numbersign == 0x00000023
-  XK_dollar == 0x00000024
-  XK_percent == 0x00000025
-  XK_ampersand == 0x00000026
-  XK_apostrophe == 0x00000027
-  XK_quoteright == 0x00000027 # deprecated 
-  XK_parenleft == 0x00000028
-  XK_parenright == 0x00000029
-  XK_asterisk == 0x0000002A
-  XK_plus == 0x0000002B
-  XK_comma == 0x0000002C
-  XK_minus == 0x0000002D
-  XK_period == 0x0000002E
-  XK_slash == 0x0000002F
-  XK_0 == 0x00000030
-  XK_1 == 0x00000031
-  XK_2 == 0x00000032
-  XK_3 == 0x00000033
-  XK_4 == 0x00000034
-  XK_5 == 0x00000035
-  XK_6 == 0x00000036
-  XK_7 == 0x00000037
-  XK_8 == 0x00000038
-  XK_9 == 0x00000039
-  XK_colon == 0x0000003A
-  XK_semicolon == 0x0000003B
-  XK_less == 0x0000003C
-  XK_equal == 0x0000003D
-  XK_greater == 0x0000003E
-  XK_question == 0x0000003F
-  XK_at == 0x00000040
-  XKc_A == 0x00000041
-  XKc_B == 0x00000042
-  XKc_C == 0x00000043
-  XKc_D == 0x00000044
-  XKc_E == 0x00000045
-  XKc_F == 0x00000046
-  XKc_G == 0x00000047
-  XKc_H == 0x00000048
-  XKc_I == 0x00000049
-  XKc_J == 0x0000004A
-  XKc_K == 0x0000004B
-  XKc_L == 0x0000004C
-  XKc_M == 0x0000004D
-  XKc_N == 0x0000004E
-  XKc_O == 0x0000004F
-  XKc_P == 0x00000050
-  XKc_Q == 0x00000051
-  XKc_R == 0x00000052
-  XKc_S == 0x00000053
-  XKc_T == 0x00000054
-  XKc_U == 0x00000055
-  XKc_V == 0x00000056
-  XKc_W == 0x00000057
-  XKc_X == 0x00000058
-  XKc_Y == 0x00000059
-  XKc_Z == 0x0000005A
-  XK_bracketleft == 0x0000005B
-  XK_backslash == 0x0000005C
-  XK_bracketright == 0x0000005D
-  XK_asciicircum == 0x0000005E
-  XK_underscore == 0x0000005F
-  XK_grave == 0x00000060
-  XK_quoteleft == 0x00000060  # deprecated 
-  XK_a == 0x00000061
-  XK_b == 0x00000062
-  XK_c == 0x00000063
-  XK_d == 0x00000064
-  XK_e == 0x00000065
-  XK_f == 0x00000066
-  XK_g == 0x00000067
-  XK_h == 0x00000068
-  XK_i == 0x00000069
-  XK_j == 0x0000006A
-  XK_k == 0x0000006B
-  XK_l == 0x0000006C
-  XK_m == 0x0000006D
-  XK_n == 0x0000006E
-  XK_o == 0x0000006F
-  XK_p == 0x00000070
-  XK_q == 0x00000071
-  XK_r == 0x00000072
-  XK_s == 0x00000073
-  XK_t == 0x00000074
-  XK_u == 0x00000075
-  XK_v == 0x00000076
-  XK_w == 0x00000077
-  XK_x == 0x00000078
-  XK_y == 0x00000079
-  XK_z == 0x0000007A
-  XK_braceleft == 0x0000007B
-  XK_bar == 0x0000007C
-  XK_braceright == 0x0000007D
-  XK_asciitilde == 0x0000007E
-  XK_nobreakspace == 0x000000A0
-  XK_exclamdown == 0x000000A1
-  XK_cent == 0x000000A2
-  XK_sterling == 0x000000A3
-  XK_currency == 0x000000A4
-  XK_yen == 0x000000A5
-  XK_brokenbar == 0x000000A6
-  XK_section == 0x000000A7
-  XK_diaeresis == 0x000000A8
-  XK_copyright == 0x000000A9
-  XK_ordfeminine == 0x000000AA
-  XK_guillemotleft == 0x000000AB # left angle quotation mark 
-  XK_notsign == 0x000000AC
-  XK_hyphen == 0x000000AD
-  XK_registered == 0x000000AE
-  XK_macron == 0x000000AF
-  XK_degree == 0x000000B0
-  XK_plusminus == 0x000000B1
-  XK_twosuperior == 0x000000B2
-  XK_threesuperior == 0x000000B3
-  XK_acute == 0x000000B4
-  XK_mu == 0x000000B5
-  XK_paragraph == 0x000000B6
-  XK_periodcentered == 0x000000B7
-  XK_cedilla == 0x000000B8
-  XK_onesuperior == 0x000000B9
-  XK_masculine == 0x000000BA
-  XK_guillemotright == 0x000000BB # right angle quotation mark 
-  XK_onequarter == 0x000000BC
-  XK_onehalf == 0x000000BD
-  XK_threequarters == 0x000000BE
-  XK_questiondown == 0x000000BF
-  XKc_Agrave == 0x000000C0
-  XKc_Aacute == 0x000000C1
-  XKc_Acircumflex == 0x000000C2
-  XKc_Atilde == 0x000000C3
-  XKc_Adiaeresis == 0x000000C4
-  XKc_Aring == 0x000000C5
-  XKc_AE == 0x000000C6
-  XKc_Ccedilla == 0x000000C7
-  XKc_Egrave == 0x000000C8
-  XKc_Eacute == 0x000000C9
-  XKc_Ecircumflex == 0x000000CA
-  XKc_Ediaeresis == 0x000000CB
-  XKc_Igrave == 0x000000CC
-  XKc_Iacute == 0x000000CD
-  XKc_Icircumflex == 0x000000CE
-  XKc_Idiaeresis == 0x000000CF
-  XKc_ETH == 0x000000D0
-  XKc_Ntilde == 0x000000D1
-  XKc_Ograve == 0x000000D2
-  XKc_Oacute == 0x000000D3
-  XKc_Ocircumflex == 0x000000D4
-  XKc_Otilde == 0x000000D5
-  XKc_Odiaeresis == 0x000000D6
-  XK_multiply == 0x000000D7
-  XKc_Ooblique == 0x000000D8
-  XKc_Oslash == XKc_Ooblique
-  XKc_Ugrave == 0x000000D9
-  XKc_Uacute == 0x000000DA
-  XKc_Ucircumflex == 0x000000DB
-  XKc_Udiaeresis == 0x000000DC
-  XKc_Yacute == 0x000000DD
-  XKc_THORN == 0x000000DE
-  XK_ssharp == 0x000000DF
-  XK_agrave == 0x000000E0
-  XK_aacute == 0x000000E1
-  XK_acircumflex == 0x000000E2
-  XK_atilde == 0x000000E3
-  XK_adiaeresis == 0x000000E4
-  XK_aring == 0x000000E5
-  XK_ae == 0x000000E6
-  XK_ccedilla == 0x000000E7
-  XK_egrave == 0x000000E8
-  XK_eacute == 0x000000E9
-  XK_ecircumflex == 0x000000EA
-  XK_ediaeresis == 0x000000EB
-  XK_igrave == 0x000000EC
-  XK_iacute == 0x000000ED
-  XK_icircumflex == 0x000000EE
-  XK_idiaeresis == 0x000000EF
-  XK_eth == 0x000000F0
-  XK_ntilde == 0x000000F1
-  XK_ograve == 0x000000F2
-  XK_oacute == 0x000000F3
-  XK_ocircumflex == 0x000000F4
-  XK_otilde == 0x000000F5
-  XK_odiaeresis == 0x000000F6
-  XK_division == 0x000000F7
-  XK_oslash == 0x000000F8
-  XK_ooblique == XK_oslash
-  XK_ugrave == 0x000000F9
-  XK_uacute == 0x000000FA
-  XK_ucircumflex == 0x000000FB
-  XK_udiaeresis == 0x000000FC
-  XK_yacute == 0x000000FD
-  XK_thorn == 0x000000FE
-  XK_ydiaeresis == 0x000000FF
-# XK_LATIN1 
-#*
-# *   Latin 2
-# *   Byte 3 = 1
-# *
-
-when defined(XK_LATIN2): 
-  XKc_Aogonek == 0x000001A1
-  XK_breve == 0x000001A2
-  XKc_Lstroke == 0x000001A3
-  XKc_Lcaron == 0x000001A5
-  XKc_Sacute == 0x000001A6
-  XKc_Scaron == 0x000001A9
-  XKc_Scedilla == 0x000001AA
-  XKc_Tcaron == 0x000001AB
-  XKc_Zacute == 0x000001AC
-  XKc_Zcaron == 0x000001AE
-  XKc_Zabovedot == 0x000001AF
-  XK_aogonek == 0x000001B1
-  XK_ogonek == 0x000001B2
-  XK_lstroke == 0x000001B3
-  XK_lcaron == 0x000001B5
-  XK_sacute == 0x000001B6
-  XK_caron == 0x000001B7
-  XK_scaron == 0x000001B9
-  XK_scedilla == 0x000001BA
-  XK_tcaron == 0x000001BB
-  XK_zacute == 0x000001BC
-  XK_doubleacute == 0x000001BD
-  XK_zcaron == 0x000001BE
-  XK_zabovedot == 0x000001BF
-  XKc_Racute == 0x000001C0
-  XKc_Abreve == 0x000001C3
-  XKc_Lacute == 0x000001C5
-  XKc_Cacute == 0x000001C6
-  XKc_Ccaron == 0x000001C8
-  XKc_Eogonek == 0x000001CA
-  XKc_Ecaron == 0x000001CC
-  XKc_Dcaron == 0x000001CF
-  XKc_Dstroke == 0x000001D0
-  XKc_Nacute == 0x000001D1
-  XKc_Ncaron == 0x000001D2
-  XKc_Odoubleacute == 0x000001D5
-  XKc_Rcaron == 0x000001D8
-  XKc_Uring == 0x000001D9
-  XKc_Udoubleacute == 0x000001DB
-  XKc_Tcedilla == 0x000001DE
-  XK_racute == 0x000001E0
-  XK_abreve == 0x000001E3
-  XK_lacute == 0x000001E5
-  XK_cacute == 0x000001E6
-  XK_ccaron == 0x000001E8
-  XK_eogonek == 0x000001EA
-  XK_ecaron == 0x000001EC
-  XK_dcaron == 0x000001EF
-  XK_dstroke == 0x000001F0
-  XK_nacute == 0x000001F1
-  XK_ncaron == 0x000001F2
-  XK_odoubleacute == 0x000001F5
-  XK_udoubleacute == 0x000001FB
-  XK_rcaron == 0x000001F8
-  XK_uring == 0x000001F9
-  XK_tcedilla == 0x000001FE
-  XK_abovedot == 0x000001FF
-# XK_LATIN2 
-#*
-# *   Latin 3
-# *   Byte 3 = 2
-# *
-
-when defined(XK_LATIN3): 
-  XKc_Hstroke == 0x000002A1
-  XKc_Hcircumflex == 0x000002A6
-  XKc_Iabovedot == 0x000002A9
-  XKc_Gbreve == 0x000002AB
-  XKc_Jcircumflex == 0x000002AC
-  XK_hstroke == 0x000002B1
-  XK_hcircumflex == 0x000002B6
-  XK_idotless == 0x000002B9
-  XK_gbreve == 0x000002BB
-  XK_jcircumflex == 0x000002BC
-  XKc_Cabovedot == 0x000002C5
-  XKc_Ccircumflex == 0x000002C6
-  XKc_Gabovedot == 0x000002D5
-  XKc_Gcircumflex == 0x000002D8
-  XKc_Ubreve == 0x000002DD
-  XKc_Scircumflex == 0x000002DE
-  XK_cabovedot == 0x000002E5
-  XK_ccircumflex == 0x000002E6
-  XK_gabovedot == 0x000002F5
-  XK_gcircumflex == 0x000002F8
-  XK_ubreve == 0x000002FD
-  XK_scircumflex == 0x000002FE
-# XK_LATIN3 
-#*
-# *   Latin 4
-# *   Byte 3 = 3
-# *
-
-when defined(XK_LATIN4): 
-  XK_kra == 0x000003A2
-  XK_kappa == 0x000003A2      # deprecated 
-  XKc_Rcedilla == 0x000003A3
-  XKc_Itilde == 0x000003A5
-  XKc_Lcedilla == 0x000003A6
-  XKc_Emacron == 0x000003AA
-  XKc_Gcedilla == 0x000003AB
-  XKc_Tslash == 0x000003AC
-  XK_rcedilla == 0x000003B3
-  XK_itilde == 0x000003B5
-  XK_lcedilla == 0x000003B6
-  XK_emacron == 0x000003BA
-  XK_gcedilla == 0x000003BB
-  XK_tslash == 0x000003BC
-  XKc_ENG == 0x000003BD
-  XK_eng == 0x000003BF
-  XKc_Amacron == 0x000003C0
-  XKc_Iogonek == 0x000003C7
-  XKc_Eabovedot == 0x000003CC
-  XKc_Imacron == 0x000003CF
-  XKc_Ncedilla == 0x000003D1
-  XKc_Omacron == 0x000003D2
-  XKc_Kcedilla == 0x000003D3
-  XKc_Uogonek == 0x000003D9
-  XKc_Utilde == 0x000003DD
-  XKc_Umacron == 0x000003DE
-  XK_amacron == 0x000003E0
-  XK_iogonek == 0x000003E7
-  XK_eabovedot == 0x000003EC
-  XK_imacron == 0x000003EF
-  XK_ncedilla == 0x000003F1
-  XK_omacron == 0x000003F2
-  XK_kcedilla == 0x000003F3
-  XK_uogonek == 0x000003F9
-  XK_utilde == 0x000003FD
-  XK_umacron == 0x000003FE
-# XK_LATIN4 
-#*
-# * Latin-8
-# * Byte 3 = 18
-# *
-
-when defined(XK_LATIN8): 
-  XKc_Babovedot == 0x000012A1
-  XK_babovedot == 0x000012A2
-  XKc_Dabovedot == 0x000012A6
-  XKc_Wgrave == 0x000012A8
-  XKc_Wacute == 0x000012AA
-  XK_dabovedot == 0x000012AB
-  XKc_Ygrave == 0x000012AC
-  XKc_Fabovedot == 0x000012B0
-  XK_fabovedot == 0x000012B1
-  XKc_Mabovedot == 0x000012B4
-  XK_mabovedot == 0x000012B5
-  XKc_Pabovedot == 0x000012B7
-  XK_wgrave == 0x000012B8
-  XK_pabovedot == 0x000012B9
-  XK_wacute == 0x000012BA
-  XKc_Sabovedot == 0x000012BB
-  XK_ygrave == 0x000012BC
-  XKc_Wdiaeresis == 0x000012BD
-  XK_wdiaeresis == 0x000012BE
-  XK_sabovedot == 0x000012BF
-  XKc_Wcircumflex == 0x000012D0
-  XKc_Tabovedot == 0x000012D7
-  XKc_Ycircumflex == 0x000012DE
-  XK_wcircumflex == 0x000012F0
-  XK_tabovedot == 0x000012F7
-  XK_ycircumflex == 0x000012FE
-# XK_LATIN8 
-#*
-# * Latin-9 (a.k.a. Latin-0)
-# * Byte 3 = 19
-# *
-
-when defined(XK_LATIN9): 
-  XKc_OE == 0x000013BC
-  XK_oe == 0x000013BD
-  XKc_Ydiaeresis == 0x000013BE
-# XK_LATIN9 
-#*
-# * Katakana
-# * Byte 3 = 4
-# *
-
-when defined(XK_KATAKANA): 
-  XK_overline == 0x0000047E
-  XK_kana_fullstop == 0x000004A1
-  XK_kana_openingbracket == 0x000004A2
-  XK_kana_closingbracket == 0x000004A3
-  XK_kana_comma == 0x000004A4
-  XK_kana_conjunctive == 0x000004A5
-  XK_kana_middledot == 0x000004A5 # deprecated 
-  XKc_kana_WO == 0x000004A6
-  XK_kana_a == 0x000004A7
-  XK_kana_i == 0x000004A8
-  XK_kana_u == 0x000004A9
-  XK_kana_e == 0x000004AA
-  XK_kana_o == 0x000004AB
-  XK_kana_ya == 0x000004AC
-  XK_kana_yu == 0x000004AD
-  XK_kana_yo == 0x000004AE
-  XK_kana_tsu == 0x000004AF
-  XK_kana_tu == 0x000004AF    # deprecated 
-  XK_prolongedsound == 0x000004B0
-  XKc_kana_A == 0x000004B1
-  XKc_kana_I == 0x000004B2
-  XKc_kana_U == 0x000004B3
-  XKc_kana_E == 0x000004B4
-  XKc_kana_O == 0x000004B5
-  XKc_kana_KA == 0x000004B6
-  XKc_kana_KI == 0x000004B7
-  XKc_kana_KU == 0x000004B8
-  XKc_kana_KE == 0x000004B9
-  XKc_kana_KO == 0x000004BA
-  XKc_kana_SA == 0x000004BB
-  XKc_kana_SHI == 0x000004BC
-  XKc_kana_SU == 0x000004BD
-  XKc_kana_SE == 0x000004BE
-  XKc_kana_SO == 0x000004BF
-  XKc_kana_TA == 0x000004C0
-  XKc_kana_CHI == 0x000004C1
-  XKc_kana_TI == 0x000004C1   # deprecated 
-  XKc_kana_TSU == 0x000004C2
-  XKc_kana_TU == 0x000004C2   # deprecated 
-  XKc_kana_TE == 0x000004C3
-  XKc_kana_TO == 0x000004C4
-  XKc_kana_NA == 0x000004C5
-  XKc_kana_NI == 0x000004C6
-  XKc_kana_NU == 0x000004C7
-  XKc_kana_NE == 0x000004C8
-  XKc_kana_NO == 0x000004C9
-  XKc_kana_HA == 0x000004CA
-  XKc_kana_HI == 0x000004CB
-  XKc_kana_FU == 0x000004CC
-  XKc_kana_HU == 0x000004CC   # deprecated 
-  XKc_kana_HE == 0x000004CD
-  XKc_kana_HO == 0x000004CE
-  XKc_kana_MA == 0x000004CF
-  XKc_kana_MI == 0x000004D0
-  XKc_kana_MU == 0x000004D1
-  XKc_kana_ME == 0x000004D2
-  XKc_kana_MO == 0x000004D3
-  XKc_kana_YA == 0x000004D4
-  XKc_kana_YU == 0x000004D5
-  XKc_kana_YO == 0x000004D6
-  XKc_kana_RA == 0x000004D7
-  XKc_kana_RI == 0x000004D8
-  XKc_kana_RU == 0x000004D9
-  XKc_kana_RE == 0x000004DA
-  XKc_kana_RO == 0x000004DB
-  XKc_kana_WA == 0x000004DC
-  XKc_kana_N == 0x000004DD
-  XK_voicedsound == 0x000004DE
-  XK_semivoicedsound == 0x000004DF
-  XK_kana_switch == 0x0000FF7E # Alias for mode_switch 
-# XK_KATAKANA 
-#*
-# *  Arabic
-# *  Byte 3 = 5
-# *
-
-when defined(XK_ARABIC): 
-  XK_Farsi_0 == 0x00000590
-  XK_Farsi_1 == 0x00000591
-  XK_Farsi_2 == 0x00000592
-  XK_Farsi_3 == 0x00000593
-  XK_Farsi_4 == 0x00000594
-  XK_Farsi_5 == 0x00000595
-  XK_Farsi_6 == 0x00000596
-  XK_Farsi_7 == 0x00000597
-  XK_Farsi_8 == 0x00000598
-  XK_Farsi_9 == 0x00000599
-  XK_Arabic_percent == 0x000005A5
-  XK_Arabic_superscript_alef == 0x000005A6
-  XK_Arabic_tteh == 0x000005A7
-  XK_Arabic_peh == 0x000005A8
-  XK_Arabic_tcheh == 0x000005A9
-  XK_Arabic_ddal == 0x000005AA
-  XK_Arabic_rreh == 0x000005AB
-  XK_Arabic_comma == 0x000005AC
-  XK_Arabic_fullstop == 0x000005AE
-  XK_Arabic_0 == 0x000005B0
-  XK_Arabic_1 == 0x000005B1
-  XK_Arabic_2 == 0x000005B2
-  XK_Arabic_3 == 0x000005B3
-  XK_Arabic_4 == 0x000005B4
-  XK_Arabic_5 == 0x000005B5
-  XK_Arabic_6 == 0x000005B6
-  XK_Arabic_7 == 0x000005B7
-  XK_Arabic_8 == 0x000005B8
-  XK_Arabic_9 == 0x000005B9
-  XK_Arabic_semicolon == 0x000005BB
-  XK_Arabic_question_mark == 0x000005BF
-  XK_Arabic_hamza == 0x000005C1
-  XK_Arabic_maddaonalef == 0x000005C2
-  XK_Arabic_hamzaonalef == 0x000005C3
-  XK_Arabic_hamzaonwaw == 0x000005C4
-  XK_Arabic_hamzaunderalef == 0x000005C5
-  XK_Arabic_hamzaonyeh == 0x000005C6
-  XK_Arabic_alef == 0x000005C7
-  XK_Arabic_beh == 0x000005C8
-  XK_Arabic_tehmarbuta == 0x000005C9
-  XK_Arabic_teh == 0x000005CA
-  XK_Arabic_theh == 0x000005CB
-  XK_Arabic_jeem == 0x000005CC
-  XK_Arabic_hah == 0x000005CD
-  XK_Arabic_khah == 0x000005CE
-  XK_Arabic_dal == 0x000005CF
-  XK_Arabic_thal == 0x000005D0
-  XK_Arabic_ra == 0x000005D1
-  XK_Arabic_zain == 0x000005D2
-  XK_Arabic_seen == 0x000005D3
-  XK_Arabic_sheen == 0x000005D4
-  XK_Arabic_sad == 0x000005D5
-  XK_Arabic_dad == 0x000005D6
-  XK_Arabic_tah == 0x000005D7
-  XK_Arabic_zah == 0x000005D8
-  XK_Arabic_ain == 0x000005D9
-  XK_Arabic_ghain == 0x000005DA
-  XK_Arabic_tatweel == 0x000005E0
-  XK_Arabic_feh == 0x000005E1
-  XK_Arabic_qaf == 0x000005E2
-  XK_Arabic_kaf == 0x000005E3
-  XK_Arabic_lam == 0x000005E4
-  XK_Arabic_meem == 0x000005E5
-  XK_Arabic_noon == 0x000005E6
-  XK_Arabic_ha == 0x000005E7
-  XK_Arabic_heh == 0x000005E7 # deprecated 
-  XK_Arabic_waw == 0x000005E8
-  XK_Arabic_alefmaksura == 0x000005E9
-  XK_Arabic_yeh == 0x000005EA
-  XK_Arabic_fathatan == 0x000005EB
-  XK_Arabic_dammatan == 0x000005EC
-  XK_Arabic_kasratan == 0x000005ED
-  XK_Arabic_fatha == 0x000005EE
-  XK_Arabic_damma == 0x000005EF
-  XK_Arabic_kasra == 0x000005F0
-  XK_Arabic_shadda == 0x000005F1
-  XK_Arabic_sukun == 0x000005F2
-  XK_Arabic_madda_above == 0x000005F3
-  XK_Arabic_hamza_above == 0x000005F4
-  XK_Arabic_hamza_below == 0x000005F5
-  XK_Arabic_jeh == 0x000005F6
-  XK_Arabic_veh == 0x000005F7
-  XK_Arabic_keheh == 0x000005F8
-  XK_Arabic_gaf == 0x000005F9
-  XK_Arabic_noon_ghunna == 0x000005FA
-  XK_Arabic_heh_doachashmee == 0x000005FB
-  XK_Farsi_yeh == 0x000005FC
-  XK_Arabic_farsi_yeh == XK_Farsi_yeh
-  XK_Arabic_yeh_baree == 0x000005FD
-  XK_Arabic_heh_goal == 0x000005FE
-  XK_Arabic_switch == 0x0000FF7E # Alias for mode_switch 
-# XK_ARABIC 
-#*
-# * Cyrillic
-# * Byte 3 = 6
-# *
-
-when defined(XK_CYRILLIC): 
-  XKc_Cyrillic_GHE_bar == 0x00000680
-  XK_Cyrillic_ghe_bar == 0x00000690
-  XKc_Cyrillic_ZHE_descender == 0x00000681
-  XK_Cyrillic_zhe_descender == 0x00000691
-  XKc_Cyrillic_KA_descender == 0x00000682
-  XK_Cyrillic_ka_descender == 0x00000692
-  XKc_Cyrillic_KA_vertstroke == 0x00000683
-  XK_Cyrillic_ka_vertstroke == 0x00000693
-  XKc_Cyrillic_EN_descender == 0x00000684
-  XK_Cyrillic_en_descender == 0x00000694
-  XKc_Cyrillic_U_straight == 0x00000685
-  XK_Cyrillic_u_straight == 0x00000695
-  XKc_Cyrillic_U_straight_bar == 0x00000686
-  XK_Cyrillic_u_straight_bar == 0x00000696
-  XKc_Cyrillic_HA_descender == 0x00000687
-  XK_Cyrillic_ha_descender == 0x00000697
-  XKc_Cyrillic_CHE_descender == 0x00000688
-  XK_Cyrillic_che_descender == 0x00000698
-  XKc_Cyrillic_CHE_vertstroke == 0x00000689
-  XK_Cyrillic_che_vertstroke == 0x00000699
-  XKc_Cyrillic_SHHA == 0x0000068A
-  XK_Cyrillic_shha == 0x0000069A
-  XKc_Cyrillic_SCHWA == 0x0000068C
-  XK_Cyrillic_schwa == 0x0000069C
-  XKc_Cyrillic_I_macron == 0x0000068D
-  XK_Cyrillic_i_macron == 0x0000069D
-  XKc_Cyrillic_O_bar == 0x0000068E
-  XK_Cyrillic_o_bar == 0x0000069E
-  XKc_Cyrillic_U_macron == 0x0000068F
-  XK_Cyrillic_u_macron == 0x0000069F
-  XK_Serbian_dje == 0x000006A1
-  XK_Macedonia_gje == 0x000006A2
-  XK_Cyrillic_io == 0x000006A3
-  XK_Ukrainian_ie == 0x000006A4
-  XK_Ukranian_je == 0x000006A4 # deprecated 
-  XK_Macedonia_dse == 0x000006A5
-  XK_Ukrainian_i == 0x000006A6
-  XK_Ukranian_i == 0x000006A6 # deprecated 
-  XK_Ukrainian_yi == 0x000006A7
-  XK_Ukranian_yi == 0x000006A7 # deprecated 
-  XK_Cyrillic_je == 0x000006A8
-  XK_Serbian_je == 0x000006A8 # deprecated 
-  XK_Cyrillic_lje == 0x000006A9
-  XK_Serbian_lje == 0x000006A9 # deprecated 
-  XK_Cyrillic_nje == 0x000006AA
-  XK_Serbian_nje == 0x000006AA # deprecated 
-  XK_Serbian_tshe == 0x000006AB
-  XK_Macedonia_kje == 0x000006AC
-  XK_Ukrainian_ghe_with_upturn == 0x000006AD
-  XK_Byelorussian_shortu == 0x000006AE
-  XK_Cyrillic_dzhe == 0x000006AF
-  XK_Serbian_dze == 0x000006AF # deprecated 
-  XK_numerosign == 0x000006B0
-  XKc_Serbian_DJE == 0x000006B1
-  XKc_Macedonia_GJE == 0x000006B2
-  XKc_Cyrillic_IO == 0x000006B3
-  XKc_Ukrainian_IE == 0x000006B4
-  XKc_Ukranian_JE == 0x000006B4 # deprecated 
-  XKc_Macedonia_DSE == 0x000006B5
-  XKc_Ukrainian_I == 0x000006B6
-  XKc_Ukranian_I == 0x000006B6 # deprecated 
-  XKc_Ukrainian_YI == 0x000006B7
-  XKc_Ukranian_YI == 0x000006B7 # deprecated 
-  XKc_Cyrillic_JE == 0x000006B8
-  XKc_Serbian_JE == 0x000006B8 # deprecated 
-  XKc_Cyrillic_LJE == 0x000006B9
-  XKc_Serbian_LJE == 0x000006B9 # deprecated 
-  XKc_Cyrillic_NJE == 0x000006BA
-  XKc_Serbian_NJE == 0x000006BA # deprecated 
-  XKc_Serbian_TSHE == 0x000006BB
-  XKc_Macedonia_KJE == 0x000006BC
-  XKc_Ukrainian_GHE_WITH_UPTURN == 0x000006BD
-  XKc_Byelorussian_SHORTU == 0x000006BE
-  XKc_Cyrillic_DZHE == 0x000006BF
-  XKc_Serbian_DZE == 0x000006BF # deprecated 
-  XK_Cyrillic_yu == 0x000006C0
-  XK_Cyrillic_a == 0x000006C1
-  XK_Cyrillic_be == 0x000006C2
-  XK_Cyrillic_tse == 0x000006C3
-  XK_Cyrillic_de == 0x000006C4
-  XK_Cyrillic_ie == 0x000006C5
-  XK_Cyrillic_ef == 0x000006C6
-  XK_Cyrillic_ghe == 0x000006C7
-  XK_Cyrillic_ha == 0x000006C8
-  XK_Cyrillic_i == 0x000006C9
-  XK_Cyrillic_shorti == 0x000006CA
-  XK_Cyrillic_ka == 0x000006CB
-  XK_Cyrillic_el == 0x000006CC
-  XK_Cyrillic_em == 0x000006CD
-  XK_Cyrillic_en == 0x000006CE
-  XK_Cyrillic_o == 0x000006CF
-  XK_Cyrillic_pe == 0x000006D0
-  XK_Cyrillic_ya == 0x000006D1
-  XK_Cyrillic_er == 0x000006D2
-  XK_Cyrillic_es == 0x000006D3
-  XK_Cyrillic_te == 0x000006D4
-  XK_Cyrillic_u == 0x000006D5
-  XK_Cyrillic_zhe == 0x000006D6
-  XK_Cyrillic_ve == 0x000006D7
-  XK_Cyrillic_softsign == 0x000006D8
-  XK_Cyrillic_yeru == 0x000006D9
-  XK_Cyrillic_ze == 0x000006DA
-  XK_Cyrillic_sha == 0x000006DB
-  XK_Cyrillic_e == 0x000006DC
-  XK_Cyrillic_shcha == 0x000006DD
-  XK_Cyrillic_che == 0x000006DE
-  XK_Cyrillic_hardsign == 0x000006DF
-  XKc_Cyrillic_YU == 0x000006E0
-  XKc_Cyrillic_A == 0x000006E1
-  XKc_Cyrillic_BE == 0x000006E2
-  XKc_Cyrillic_TSE == 0x000006E3
-  XKc_Cyrillic_DE == 0x000006E4
-  XKc_Cyrillic_IE == 0x000006E5
-  XKc_Cyrillic_EF == 0x000006E6
-  XKc_Cyrillic_GHE == 0x000006E7
-  XKc_Cyrillic_HA == 0x000006E8
-  XKc_Cyrillic_I == 0x000006E9
-  XKc_Cyrillic_SHORTI == 0x000006EA
-  XKc_Cyrillic_KA == 0x000006EB
-  XKc_Cyrillic_EL == 0x000006EC
-  XKc_Cyrillic_EM == 0x000006ED
-  XKc_Cyrillic_EN == 0x000006EE
-  XKc_Cyrillic_O == 0x000006EF
-  XKc_Cyrillic_PE == 0x000006F0
-  XKc_Cyrillic_YA == 0x000006F1
-  XKc_Cyrillic_ER == 0x000006F2
-  XKc_Cyrillic_ES == 0x000006F3
-  XKc_Cyrillic_TE == 0x000006F4
-  XKc_Cyrillic_U == 0x000006F5
-  XKc_Cyrillic_ZHE == 0x000006F6
-  XKc_Cyrillic_VE == 0x000006F7
-  XKc_Cyrillic_SOFTSIGN == 0x000006F8
-  XKc_Cyrillic_YERU == 0x000006F9
-  XKc_Cyrillic_ZE == 0x000006FA
-  XKc_Cyrillic_SHA == 0x000006FB
-  XKc_Cyrillic_E == 0x000006FC
-  XKc_Cyrillic_SHCHA == 0x000006FD
-  XKc_Cyrillic_CHE == 0x000006FE
-  XKc_Cyrillic_HARDSIGN == 0x000006FF
-# XK_CYRILLIC 
-#*
-# * Greek
-# * Byte 3 = 7
-# *
-
-when defined(XK_GREEK): 
-  XKc_Greek_ALPHAaccent == 0x000007A1
-  XKc_Greek_EPSILONaccent == 0x000007A2
-  XKc_Greek_ETAaccent == 0x000007A3
-  XKc_Greek_IOTAaccent == 0x000007A4
-  XKc_Greek_IOTAdieresis == 0x000007A5
-  XKc_Greek_IOTAdiaeresis == XKc_Greek_IOTAdieresis # old typo 
-  XKc_Greek_OMICRONaccent == 0x000007A7
-  XKc_Greek_UPSILONaccent == 0x000007A8
-  XKc_Greek_UPSILONdieresis == 0x000007A9
-  XKc_Greek_OMEGAaccent == 0x000007AB
-  XK_Greek_accentdieresis == 0x000007AE
-  XK_Greek_horizbar == 0x000007AF
-  XK_Greek_alphaaccent == 0x000007B1
-  XK_Greek_epsilonaccent == 0x000007B2
-  XK_Greek_etaaccent == 0x000007B3
-  XK_Greek_iotaaccent == 0x000007B4
-  XK_Greek_iotadieresis == 0x000007B5
-  XK_Greek_iotaaccentdieresis == 0x000007B6
-  XK_Greek_omicronaccent == 0x000007B7
-  XK_Greek_upsilonaccent == 0x000007B8
-  XK_Greek_upsilondieresis == 0x000007B9
-  XK_Greek_upsilonaccentdieresis == 0x000007BA
-  XK_Greek_omegaaccent == 0x000007BB
-  XKc_Greek_ALPHA == 0x000007C1
-  XKc_Greek_BETA == 0x000007C2
-  XKc_Greek_GAMMA == 0x000007C3
-  XKc_Greek_DELTA == 0x000007C4
-  XKc_Greek_EPSILON == 0x000007C5
-  XKc_Greek_ZETA == 0x000007C6
-  XKc_Greek_ETA == 0x000007C7
-  XKc_Greek_THETA == 0x000007C8
-  XKc_Greek_IOTA == 0x000007C9
-  XKc_Greek_KAPPA == 0x000007CA
-  XKc_Greek_LAMDA == 0x000007CB
-  XKc_Greek_LAMBDA == 0x000007CB
-  XKc_Greek_MU == 0x000007CC
-  XKc_Greek_NU == 0x000007CD
-  XKc_Greek_XI == 0x000007CE
-  XKc_Greek_OMICRON == 0x000007CF
-  XKc_Greek_PI == 0x000007D0
-  XKc_Greek_RHO == 0x000007D1
-  XKc_Greek_SIGMA == 0x000007D2
-  XKc_Greek_TAU == 0x000007D4
-  XKc_Greek_UPSILON == 0x000007D5
-  XKc_Greek_PHI == 0x000007D6
-  XKc_Greek_CHI == 0x000007D7
-  XKc_Greek_PSI == 0x000007D8
-  XKc_Greek_OMEGA == 0x000007D9
-  XK_Greek_alpha == 0x000007E1
-  XK_Greek_beta == 0x000007E2
-  XK_Greek_gamma == 0x000007E3
-  XK_Greek_delta == 0x000007E4
-  XK_Greek_epsilon == 0x000007E5
-  XK_Greek_zeta == 0x000007E6
-  XK_Greek_eta == 0x000007E7
-  XK_Greek_theta == 0x000007E8
-  XK_Greek_iota == 0x000007E9
-  XK_Greek_kappa == 0x000007EA
-  XK_Greek_lamda == 0x000007EB
-  XK_Greek_lambda == 0x000007EB
-  XK_Greek_mu == 0x000007EC
-  XK_Greek_nu == 0x000007ED
-  XK_Greek_xi == 0x000007EE
-  XK_Greek_omicron == 0x000007EF
-  XK_Greek_pi == 0x000007F0
-  XK_Greek_rho == 0x000007F1
-  XK_Greek_sigma == 0x000007F2
-  XK_Greek_finalsmallsigma == 0x000007F3
-  XK_Greek_tau == 0x000007F4
-  XK_Greek_upsilon == 0x000007F5
-  XK_Greek_phi == 0x000007F6
-  XK_Greek_chi == 0x000007F7
-  XK_Greek_psi == 0x000007F8
-  XK_Greek_omega == 0x000007F9
-  XK_Greek_switch == 0x0000FF7E # Alias for mode_switch 
-# XK_GREEK 
-#*
-# * Technical
-# * Byte 3 = 8
-# *
-
-when defined(XK_TECHNICAL): 
-  XK_leftradical == 0x000008A1
-  XK_topleftradical == 0x000008A2
-  XK_horizconnector == 0x000008A3
-  XK_topintegral == 0x000008A4
-  XK_botintegral == 0x000008A5
-  XK_vertconnector == 0x000008A6
-  XK_topleftsqbracket == 0x000008A7
-  XK_botleftsqbracket == 0x000008A8
-  XK_toprightsqbracket == 0x000008A9
-  XK_botrightsqbracket == 0x000008AA
-  XK_topleftparens == 0x000008AB
-  XK_botleftparens == 0x000008AC
-  XK_toprightparens == 0x000008AD
-  XK_botrightparens == 0x000008AE
-  XK_leftmiddlecurlybrace == 0x000008AF
-  XK_rightmiddlecurlybrace == 0x000008B0
-  XK_topleftsummation == 0x000008B1
-  XK_botleftsummation == 0x000008B2
-  XK_topvertsummationconnector == 0x000008B3
-  XK_botvertsummationconnector == 0x000008B4
-  XK_toprightsummation == 0x000008B5
-  XK_botrightsummation == 0x000008B6
-  XK_rightmiddlesummation == 0x000008B7
-  XK_lessthanequal == 0x000008BC
-  XK_notequal == 0x000008BD
-  XK_greaterthanequal == 0x000008BE
-  XK_integral == 0x000008BF
-  XK_therefore == 0x000008C0
-  XK_variation == 0x000008C1
-  XK_infinity == 0x000008C2
-  XK_nabla == 0x000008C5
-  XK_approximate == 0x000008C8
-  XK_similarequal == 0x000008C9
-  XK_ifonlyif == 0x000008CD
-  XK_implies == 0x000008CE
-  XK_identical == 0x000008CF
-  XK_radical == 0x000008D6
-  XK_includedin == 0x000008DA
-  XK_includes == 0x000008DB
-  XK_intersection == 0x000008DC
-  XK_union == 0x000008DD
-  XK_logicaland == 0x000008DE
-  XK_logicalor == 0x000008DF
-  XK_partialderivative == 0x000008EF
-  XK_function == 0x000008F6
-  XK_leftarrow == 0x000008FB
-  XK_uparrow == 0x000008FC
-  XK_rightarrow == 0x000008FD
-  XK_downarrow == 0x000008FE
-# XK_TECHNICAL 
-#*
-# *  Special
-# *  Byte 3 = 9
-# *
-
-when defined(XK_SPECIAL): 
-  XK_blank == 0x000009DF
-  XK_soliddiamond == 0x000009E0
-  XK_checkerboard == 0x000009E1
-  XK_ht == 0x000009E2
-  XK_ff == 0x000009E3
-  XK_cr == 0x000009E4
-  XK_lf == 0x000009E5
-  XK_nl == 0x000009E8
-  XK_vt == 0x000009E9
-  XK_lowrightcorner == 0x000009EA
-  XK_uprightcorner == 0x000009EB
-  XK_upleftcorner == 0x000009EC
-  XK_lowleftcorner == 0x000009ED
-  XK_crossinglines == 0x000009EE
-  XK_horizlinescan1 == 0x000009EF
-  XK_horizlinescan3 == 0x000009F0
-  XK_horizlinescan5 == 0x000009F1
-  XK_horizlinescan7 == 0x000009F2
-  XK_horizlinescan9 == 0x000009F3
-  XK_leftt == 0x000009F4
-  XK_rightt == 0x000009F5
-  XK_bott == 0x000009F6
-  XK_topt == 0x000009F7
-  XK_vertbar == 0x000009F8
-# XK_SPECIAL 
-#*
-# *  Publishing
-# *  Byte 3 = a
-# *
-
-when defined(XK_PUBLISHING): 
-  XK_emspace == 0x00000AA1
-  XK_enspace == 0x00000AA2
-  XK_em3space == 0x00000AA3
-  XK_em4space == 0x00000AA4
-  XK_digitspace == 0x00000AA5
-  XK_punctspace == 0x00000AA6
-  XK_thinspace == 0x00000AA7
-  XK_hairspace == 0x00000AA8
-  XK_emdash == 0x00000AA9
-  XK_endash == 0x00000AAA
-  XK_signifblank == 0x00000AAC
-  XK_ellipsis == 0x00000AAE
-  XK_doubbaselinedot == 0x00000AAF
-  XK_onethird == 0x00000AB0
-  XK_twothirds == 0x00000AB1
-  XK_onefifth == 0x00000AB2
-  XK_twofifths == 0x00000AB3
-  XK_threefifths == 0x00000AB4
-  XK_fourfifths == 0x00000AB5
-  XK_onesixth == 0x00000AB6
-  XK_fivesixths == 0x00000AB7
-  XK_careof == 0x00000AB8
-  XK_figdash == 0x00000ABB
-  XK_leftanglebracket == 0x00000ABC
-  XK_decimalpoint == 0x00000ABD
-  XK_rightanglebracket == 0x00000ABE
-  XK_marker == 0x00000ABF
-  XK_oneeighth == 0x00000AC3
-  XK_threeeighths == 0x00000AC4
-  XK_fiveeighths == 0x00000AC5
-  XK_seveneighths == 0x00000AC6
-  XK_trademark == 0x00000AC9
-  XK_signaturemark == 0x00000ACA
-  XK_trademarkincircle == 0x00000ACB
-  XK_leftopentriangle == 0x00000ACC
-  XK_rightopentriangle == 0x00000ACD
-  XK_emopencircle == 0x00000ACE
-  XK_emopenrectangle == 0x00000ACF
-  XK_leftsinglequotemark == 0x00000AD0
-  XK_rightsinglequotemark == 0x00000AD1
-  XK_leftdoublequotemark == 0x00000AD2
-  XK_rightdoublequotemark == 0x00000AD3
-  XK_prescription == 0x00000AD4
-  XK_minutes == 0x00000AD6
-  XK_seconds == 0x00000AD7
-  XK_latincross == 0x00000AD9
-  XK_hexagram == 0x00000ADA
-  XK_filledrectbullet == 0x00000ADB
-  XK_filledlefttribullet == 0x00000ADC
-  XK_filledrighttribullet == 0x00000ADD
-  XK_emfilledcircle == 0x00000ADE
-  XK_emfilledrect == 0x00000ADF
-  XK_enopencircbullet == 0x00000AE0
-  XK_enopensquarebullet == 0x00000AE1
-  XK_openrectbullet == 0x00000AE2
-  XK_opentribulletup == 0x00000AE3
-  XK_opentribulletdown == 0x00000AE4
-  XK_openstar == 0x00000AE5
-  XK_enfilledcircbullet == 0x00000AE6
-  XK_enfilledsqbullet == 0x00000AE7
-  XK_filledtribulletup == 0x00000AE8
-  XK_filledtribulletdown == 0x00000AE9
-  XK_leftpointer == 0x00000AEA
-  XK_rightpointer == 0x00000AEB
-  XK_club == 0x00000AEC
-  XK_diamond == 0x00000AED
-  XK_heart == 0x00000AEE
-  XK_maltesecross == 0x00000AF0
-  XK_dagger == 0x00000AF1
-  XK_doubledagger == 0x00000AF2
-  XK_checkmark == 0x00000AF3
-  XK_ballotcross == 0x00000AF4
-  XK_musicalsharp == 0x00000AF5
-  XK_musicalflat == 0x00000AF6
-  XK_malesymbol == 0x00000AF7
-  XK_femalesymbol == 0x00000AF8
-  XK_telephone == 0x00000AF9
-  XK_telephonerecorder == 0x00000AFA
-  XK_phonographcopyright == 0x00000AFB
-  XK_caret == 0x00000AFC
-  XK_singlelowquotemark == 0x00000AFD
-  XK_doublelowquotemark == 0x00000AFE
-  XK_cursor == 0x00000AFF
-# XK_PUBLISHING 
-#*
-# *  APL
-# *  Byte 3 = b
-# *
-
-when defined(XK_APL): 
-  XK_leftcaret == 0x00000BA3
-  XK_rightcaret == 0x00000BA6
-  XK_downcaret == 0x00000BA8
-  XK_upcaret == 0x00000BA9
-  XK_overbar == 0x00000BC0
-  XK_downtack == 0x00000BC2
-  XK_upshoe == 0x00000BC3
-  XK_downstile == 0x00000BC4
-  XK_underbar == 0x00000BC6
-  XK_jot == 0x00000BCA
-  XK_quad == 0x00000BCC
-  XK_uptack == 0x00000BCE
-  XK_circle == 0x00000BCF
-  XK_upstile == 0x00000BD3
-  XK_downshoe == 0x00000BD6
-  XK_rightshoe == 0x00000BD8
-  XK_leftshoe == 0x00000BDA
-  XK_lefttack == 0x00000BDC
-  XK_righttack == 0x00000BFC
-# XK_APL 
-#*
-# * Hebrew
-# * Byte 3 = c
-# *
-
-when defined(XK_HEBREW): 
-  XK_hebrew_doublelowline == 0x00000CDF
-  XK_hebrew_aleph == 0x00000CE0
-  XK_hebrew_bet == 0x00000CE1
-  XK_hebrew_beth == 0x00000CE1 # deprecated 
-  XK_hebrew_gimel == 0x00000CE2
-  XK_hebrew_gimmel == 0x00000CE2 # deprecated 
-  XK_hebrew_dalet == 0x00000CE3
-  XK_hebrew_daleth == 0x00000CE3 # deprecated 
-  XK_hebrew_he == 0x00000CE4
-  XK_hebrew_waw == 0x00000CE5
-  XK_hebrew_zain == 0x00000CE6
-  XK_hebrew_zayin == 0x00000CE6 # deprecated 
-  XK_hebrew_chet == 0x00000CE7
-  XK_hebrew_het == 0x00000CE7 # deprecated 
-  XK_hebrew_tet == 0x00000CE8
-  XK_hebrew_teth == 0x00000CE8 # deprecated 
-  XK_hebrew_yod == 0x00000CE9
-  XK_hebrew_finalkaph == 0x00000CEA
-  XK_hebrew_kaph == 0x00000CEB
-  XK_hebrew_lamed == 0x00000CEC
-  XK_hebrew_finalmem == 0x00000CED
-  XK_hebrew_mem == 0x00000CEE
-  XK_hebrew_finalnun == 0x00000CEF
-  XK_hebrew_nun == 0x00000CF0
-  XK_hebrew_samech == 0x00000CF1
-  XK_hebrew_samekh == 0x00000CF1 # deprecated 
-  XK_hebrew_ayin == 0x00000CF2
-  XK_hebrew_finalpe == 0x00000CF3
-  XK_hebrew_pe == 0x00000CF4
-  XK_hebrew_finalzade == 0x00000CF5
-  XK_hebrew_finalzadi == 0x00000CF5 # deprecated 
-  XK_hebrew_zade == 0x00000CF6
-  XK_hebrew_zadi == 0x00000CF6 # deprecated 
-  XK_hebrew_qoph == 0x00000CF7
-  XK_hebrew_kuf == 0x00000CF7 # deprecated 
-  XK_hebrew_resh == 0x00000CF8
-  XK_hebrew_shin == 0x00000CF9
-  XK_hebrew_taw == 0x00000CFA
-  XK_hebrew_taf == 0x00000CFA # deprecated 
-  XK_Hebrew_switch == 0x0000FF7E # Alias for mode_switch 
-# XK_HEBREW 
-#*
-# * Thai
-# * Byte 3 = d
-# *
-
-when defined(XK_THAI): 
-  XK_Thai_kokai == 0x00000DA1
-  XK_Thai_khokhai == 0x00000DA2
-  XK_Thai_khokhuat == 0x00000DA3
-  XK_Thai_khokhwai == 0x00000DA4
-  XK_Thai_khokhon == 0x00000DA5
-  XK_Thai_khorakhang == 0x00000DA6
-  XK_Thai_ngongu == 0x00000DA7
-  XK_Thai_chochan == 0x00000DA8
-  XK_Thai_choching == 0x00000DA9
-  XK_Thai_chochang == 0x00000DAA
-  XK_Thai_soso == 0x00000DAB
-  XK_Thai_chochoe == 0x00000DAC
-  XK_Thai_yoying == 0x00000DAD
-  XK_Thai_dochada == 0x00000DAE
-  XK_Thai_topatak == 0x00000DAF
-  XK_Thai_thothan == 0x00000DB0
-  XK_Thai_thonangmontho == 0x00000DB1
-  XK_Thai_thophuthao == 0x00000DB2
-  XK_Thai_nonen == 0x00000DB3
-  XK_Thai_dodek == 0x00000DB4
-  XK_Thai_totao == 0x00000DB5
-  XK_Thai_thothung == 0x00000DB6
-  XK_Thai_thothahan == 0x00000DB7
-  XK_Thai_thothong == 0x00000DB8
-  XK_Thai_nonu == 0x00000DB9
-  XK_Thai_bobaimai == 0x00000DBA
-  XK_Thai_popla == 0x00000DBB
-  XK_Thai_phophung == 0x00000DBC
-  XK_Thai_fofa == 0x00000DBD
-  XK_Thai_phophan == 0x00000DBE
-  XK_Thai_fofan == 0x00000DBF
-  XK_Thai_phosamphao == 0x00000DC0
-  XK_Thai_moma == 0x00000DC1
-  XK_Thai_yoyak == 0x00000DC2
-  XK_Thai_rorua == 0x00000DC3
-  XK_Thai_ru == 0x00000DC4
-  XK_Thai_loling == 0x00000DC5
-  XK_Thai_lu == 0x00000DC6
-  XK_Thai_wowaen == 0x00000DC7
-  XK_Thai_sosala == 0x00000DC8
-  XK_Thai_sorusi == 0x00000DC9
-  XK_Thai_sosua == 0x00000DCA
-  XK_Thai_hohip == 0x00000DCB
-  XK_Thai_lochula == 0x00000DCC
-  XK_Thai_oang == 0x00000DCD
-  XK_Thai_honokhuk == 0x00000DCE
-  XK_Thai_paiyannoi == 0x00000DCF
-  XK_Thai_saraa == 0x00000DD0
-  XK_Thai_maihanakat == 0x00000DD1
-  XK_Thai_saraaa == 0x00000DD2
-  XK_Thai_saraam == 0x00000DD3
-  XK_Thai_sarai == 0x00000DD4
-  XK_Thai_saraii == 0x00000DD5
-  XK_Thai_saraue == 0x00000DD6
-  XK_Thai_sarauee == 0x00000DD7
-  XK_Thai_sarau == 0x00000DD8
-  XK_Thai_sarauu == 0x00000DD9
-  XK_Thai_phinthu == 0x00000DDA
-  XK_Thai_maihanakat_maitho == 0x00000DDE
-  XK_Thai_baht == 0x00000DDF
-  XK_Thai_sarae == 0x00000DE0
-  XK_Thai_saraae == 0x00000DE1
-  XK_Thai_sarao == 0x00000DE2
-  XK_Thai_saraaimaimuan == 0x00000DE3
-  XK_Thai_saraaimaimalai == 0x00000DE4
-  XK_Thai_lakkhangyao == 0x00000DE5
-  XK_Thai_maiyamok == 0x00000DE6
-  XK_Thai_maitaikhu == 0x00000DE7
-  XK_Thai_maiek == 0x00000DE8
-  XK_Thai_maitho == 0x00000DE9
-  XK_Thai_maitri == 0x00000DEA
-  XK_Thai_maichattawa == 0x00000DEB
-  XK_Thai_thanthakhat == 0x00000DEC
-  XK_Thai_nikhahit == 0x00000DED
-  XK_Thai_leksun == 0x00000DF0
-  XK_Thai_leknung == 0x00000DF1
-  XK_Thai_leksong == 0x00000DF2
-  XK_Thai_leksam == 0x00000DF3
-  XK_Thai_leksi == 0x00000DF4
-  XK_Thai_lekha == 0x00000DF5
-  XK_Thai_lekhok == 0x00000DF6
-  XK_Thai_lekchet == 0x00000DF7
-  XK_Thai_lekpaet == 0x00000DF8
-  XK_Thai_lekkao == 0x00000DF9
-# XK_THAI 
-#*
-# *   Korean
-# *   Byte 3 = e
-# *
-
-when defined(XK_KOREAN): 
-  XK_Hangul == 0x0000FF31     # Hangul start/stop(toggle) 
-  XK_Hangul_Start == 0x0000FF32 # Hangul start 
-  XK_Hangul_End == 0x0000FF33 # Hangul end, English start 
-  XK_Hangul_Hanja == 0x0000FF34 # Start Hangul->Hanja Conversion 
-  XK_Hangul_Jamo == 0x0000FF35 # Hangul Jamo mode 
-  XK_Hangul_Romaja == 0x0000FF36 # Hangul Romaja mode 
-  XK_Hangul_Codeinput == 0x0000FF37 # Hangul code input mode 
-  XK_Hangul_Jeonja == 0x0000FF38 # Jeonja mode 
-  XK_Hangul_Banja == 0x0000FF39 # Banja mode 
-  XK_Hangul_PreHanja == 0x0000FF3A # Pre Hanja conversion 
-  XK_Hangul_PostHanja == 0x0000FF3B # Post Hanja conversion 
-  XK_Hangul_SingleCandidate == 0x0000FF3C # Single candidate 
-  XK_Hangul_MultipleCandidate == 0x0000FF3D # Multiple candidate 
-  XK_Hangul_PreviousCandidate == 0x0000FF3E # Previous candidate 
-  XK_Hangul_Special == 0x0000FF3F # Special symbols 
-  XK_Hangul_switch == 0x0000FF7E # Alias for mode_switch 
-                                 # Hangul Consonant Characters 
-  XK_Hangul_Kiyeog == 0x00000EA1
-  XK_Hangul_SsangKiyeog == 0x00000EA2
-  XK_Hangul_KiyeogSios == 0x00000EA3
-  XK_Hangul_Nieun == 0x00000EA4
-  XK_Hangul_NieunJieuj == 0x00000EA5
-  XK_Hangul_NieunHieuh == 0x00000EA6
-  XK_Hangul_Dikeud == 0x00000EA7
-  XK_Hangul_SsangDikeud == 0x00000EA8
-  XK_Hangul_Rieul == 0x00000EA9
-  XK_Hangul_RieulKiyeog == 0x00000EAA
-  XK_Hangul_RieulMieum == 0x00000EAB
-  XK_Hangul_RieulPieub == 0x00000EAC
-  XK_Hangul_RieulSios == 0x00000EAD
-  XK_Hangul_RieulTieut == 0x00000EAE
-  XK_Hangul_RieulPhieuf == 0x00000EAF
-  XK_Hangul_RieulHieuh == 0x00000EB0
-  XK_Hangul_Mieum == 0x00000EB1
-  XK_Hangul_Pieub == 0x00000EB2
-  XK_Hangul_SsangPieub == 0x00000EB3
-  XK_Hangul_PieubSios == 0x00000EB4
-  XK_Hangul_Sios == 0x00000EB5
-  XK_Hangul_SsangSios == 0x00000EB6
-  XK_Hangul_Ieung == 0x00000EB7
-  XK_Hangul_Jieuj == 0x00000EB8
-  XK_Hangul_SsangJieuj == 0x00000EB9
-  XK_Hangul_Cieuc == 0x00000EBA
-  XK_Hangul_Khieuq == 0x00000EBB
-  XK_Hangul_Tieut == 0x00000EBC
-  XK_Hangul_Phieuf == 0x00000EBD
-  XK_Hangul_Hieuh == 0x00000EBE # Hangul Vowel Characters 
-  XK_Hangul_A == 0x00000EBF
-  XK_Hangul_AE == 0x00000EC0
-  XK_Hangul_YA == 0x00000EC1
-  XK_Hangul_YAE == 0x00000EC2
-  XK_Hangul_EO == 0x00000EC3
-  XK_Hangul_E == 0x00000EC4
-  XK_Hangul_YEO == 0x00000EC5
-  XK_Hangul_YE == 0x00000EC6
-  XK_Hangul_O == 0x00000EC7
-  XK_Hangul_WA == 0x00000EC8
-  XK_Hangul_WAE == 0x00000EC9
-  XK_Hangul_OE == 0x00000ECA
-  XK_Hangul_YO == 0x00000ECB
-  XK_Hangul_U == 0x00000ECC
-  XK_Hangul_WEO == 0x00000ECD
-  XK_Hangul_WE == 0x00000ECE
-  XK_Hangul_WI == 0x00000ECF
-  XK_Hangul_YU == 0x00000ED0
-  XK_Hangul_EU == 0x00000ED1
-  XK_Hangul_YI == 0x00000ED2
-  XK_Hangul_I == 0x00000ED3   # Hangul syllable-final (JongSeong) Characters 
-  XK_Hangul_J_Kiyeog == 0x00000ED4
-  XK_Hangul_J_SsangKiyeog == 0x00000ED5
-  XK_Hangul_J_KiyeogSios == 0x00000ED6
-  XK_Hangul_J_Nieun == 0x00000ED7
-  XK_Hangul_J_NieunJieuj == 0x00000ED8
-  XK_Hangul_J_NieunHieuh == 0x00000ED9
-  XK_Hangul_J_Dikeud == 0x00000EDA
-  XK_Hangul_J_Rieul == 0x00000EDB
-  XK_Hangul_J_RieulKiyeog == 0x00000EDC
-  XK_Hangul_J_RieulMieum == 0x00000EDD
-  XK_Hangul_J_RieulPieub == 0x00000EDE
-  XK_Hangul_J_RieulSios == 0x00000EDF
-  XK_Hangul_J_RieulTieut == 0x00000EE0
-  XK_Hangul_J_RieulPhieuf == 0x00000EE1
-  XK_Hangul_J_RieulHieuh == 0x00000EE2
-  XK_Hangul_J_Mieum == 0x00000EE3
-  XK_Hangul_J_Pieub == 0x00000EE4
-  XK_Hangul_J_PieubSios == 0x00000EE5
-  XK_Hangul_J_Sios == 0x00000EE6
-  XK_Hangul_J_SsangSios == 0x00000EE7
-  XK_Hangul_J_Ieung == 0x00000EE8
-  XK_Hangul_J_Jieuj == 0x00000EE9
-  XK_Hangul_J_Cieuc == 0x00000EEA
-  XK_Hangul_J_Khieuq == 0x00000EEB
-  XK_Hangul_J_Tieut == 0x00000EEC
-  XK_Hangul_J_Phieuf == 0x00000EED
-  XK_Hangul_J_Hieuh == 0x00000EEE # Ancient Hangul Consonant Characters 
-  XK_Hangul_RieulYeorinHieuh == 0x00000EEF
-  XK_Hangul_SunkyeongeumMieum == 0x00000EF0
-  XK_Hangul_SunkyeongeumPieub == 0x00000EF1
-  XK_Hangul_PanSios == 0x00000EF2
-  XK_Hangul_KkogjiDalrinIeung == 0x00000EF3
-  XK_Hangul_SunkyeongeumPhieuf == 0x00000EF4
-  XK_Hangul_YeorinHieuh == 0x00000EF5 # Ancient Hangul Vowel Characters 
-  XK_Hangul_AraeA == 0x00000EF6
-  XK_Hangul_AraeAE == 0x00000EF7 # Ancient Hangul syllable-final (JongSeong) Characters 
-  XK_Hangul_J_PanSios == 0x00000EF8
-  XK_Hangul_J_KkogjiDalrinIeung == 0x00000EF9
-  XK_Hangul_J_YeorinHieuh == 0x00000EFA # Korean currency symbol 
-  XK_Korean_Won == 0x00000EFF
-# XK_KOREAN 
-#*
-# *   Armenian
-# *   Byte 3 = = $14
-# *
-
-when defined(XK_ARMENIAN): 
-  XK_Armenian_eternity == 0x000014A1
-  XK_Armenian_ligature_ew == 0x000014A2
-  XK_Armenian_full_stop == 0x000014A3
-  XK_Armenian_verjaket == 0x000014A3
-  XK_Armenian_parenright == 0x000014A4
-  XK_Armenian_parenleft == 0x000014A5
-  XK_Armenian_guillemotright == 0x000014A6
-  XK_Armenian_guillemotleft == 0x000014A7
-  XK_Armenian_em_dash == 0x000014A8
-  XK_Armenian_dot == 0x000014A9
-  XK_Armenian_mijaket == 0x000014A9
-  XK_Armenian_separation_mark == 0x000014AA
-  XK_Armenian_but == 0x000014AA
-  XK_Armenian_comma == 0x000014AB
-  XK_Armenian_en_dash == 0x000014AC
-  XK_Armenian_hyphen == 0x000014AD
-  XK_Armenian_yentamna == 0x000014AD
-  XK_Armenian_ellipsis == 0x000014AE
-  XK_Armenian_exclam == 0x000014AF
-  XK_Armenian_amanak == 0x000014AF
-  XK_Armenian_accent == 0x000014B0
-  XK_Armenian_shesht == 0x000014B0
-  XK_Armenian_question == 0x000014B1
-  XK_Armenian_paruyk == 0x000014B1
-  XKc_Armenian_AYB == 0x000014B2
-  XK_Armenian_ayb == 0x000014B3
-  XKc_Armenian_BEN == 0x000014B4
-  XK_Armenian_ben == 0x000014B5
-  XKc_Armenian_GIM == 0x000014B6
-  XK_Armenian_gim == 0x000014B7
-  XKc_Armenian_DA == 0x000014B8
-  XK_Armenian_da == 0x000014B9
-  XKc_Armenian_YECH == 0x000014BA
-  XK_Armenian_yech == 0x000014BB
-  XKc_Armenian_ZA == 0x000014BC
-  XK_Armenian_za == 0x000014BD
-  XKc_Armenian_E == 0x000014BE
-  XK_Armenian_e == 0x000014BF
-  XKc_Armenian_AT == 0x000014C0
-  XK_Armenian_at == 0x000014C1
-  XKc_Armenian_TO == 0x000014C2
-  XK_Armenian_to == 0x000014C3
-  XKc_Armenian_ZHE == 0x000014C4
-  XK_Armenian_zhe == 0x000014C5
-  XKc_Armenian_INI == 0x000014C6
-  XK_Armenian_ini == 0x000014C7
-  XKc_Armenian_LYUN == 0x000014C8
-  XK_Armenian_lyun == 0x000014C9
-  XKc_Armenian_KHE == 0x000014CA
-  XK_Armenian_khe == 0x000014CB
-  XKc_Armenian_TSA == 0x000014CC
-  XK_Armenian_tsa == 0x000014CD
-  XKc_Armenian_KEN == 0x000014CE
-  XK_Armenian_ken == 0x000014CF
-  XKc_Armenian_HO == 0x000014D0
-  XK_Armenian_ho == 0x000014D1
-  XKc_Armenian_DZA == 0x000014D2
-  XK_Armenian_dza == 0x000014D3
-  XKc_Armenian_GHAT == 0x000014D4
-  XK_Armenian_ghat == 0x000014D5
-  XKc_Armenian_TCHE == 0x000014D6
-  XK_Armenian_tche == 0x000014D7
-  XKc_Armenian_MEN == 0x000014D8
-  XK_Armenian_men == 0x000014D9
-  XKc_Armenian_HI == 0x000014DA
-  XK_Armenian_hi == 0x000014DB
-  XKc_Armenian_NU == 0x000014DC
-  XK_Armenian_nu == 0x000014DD
-  XKc_Armenian_SHA == 0x000014DE
-  XK_Armenian_sha == 0x000014DF
-  XKc_Armenian_VO == 0x000014E0
-  XK_Armenian_vo == 0x000014E1
-  XKc_Armenian_CHA == 0x000014E2
-  XK_Armenian_cha == 0x000014E3
-  XKc_Armenian_PE == 0x000014E4
-  XK_Armenian_pe == 0x000014E5
-  XKc_Armenian_JE == 0x000014E6
-  XK_Armenian_je == 0x000014E7
-  XKc_Armenian_RA == 0x000014E8
-  XK_Armenian_ra == 0x000014E9
-  XKc_Armenian_SE == 0x000014EA
-  XK_Armenian_se == 0x000014EB
-  XKc_Armenian_VEV == 0x000014EC
-  XK_Armenian_vev == 0x000014ED
-  XKc_Armenian_TYUN == 0x000014EE
-  XK_Armenian_tyun == 0x000014EF
-  XKc_Armenian_RE == 0x000014F0
-  XK_Armenian_re == 0x000014F1
-  XKc_Armenian_TSO == 0x000014F2
-  XK_Armenian_tso == 0x000014F3
-  XKc_Armenian_VYUN == 0x000014F4
-  XK_Armenian_vyun == 0x000014F5
-  XKc_Armenian_PYUR == 0x000014F6
-  XK_Armenian_pyur == 0x000014F7
-  XKc_Armenian_KE == 0x000014F8
-  XK_Armenian_ke == 0x000014F9
-  XKc_Armenian_O == 0x000014FA
-  XK_Armenian_o == 0x000014FB
-  XKc_Armenian_FE == 0x000014FC
-  XK_Armenian_fe == 0x000014FD
-  XK_Armenian_apostrophe == 0x000014FE
-  XK_Armenian_section_sign == 0x000014FF
-# XK_ARMENIAN 
-#*
-# *   Georgian
-# *   Byte 3 = = $15
-# *
-
-when defined(XK_GEORGIAN): 
-  XK_Georgian_an == 0x000015D0
-  XK_Georgian_ban == 0x000015D1
-  XK_Georgian_gan == 0x000015D2
-  XK_Georgian_don == 0x000015D3
-  XK_Georgian_en == 0x000015D4
-  XK_Georgian_vin == 0x000015D5
-  XK_Georgian_zen == 0x000015D6
-  XK_Georgian_tan == 0x000015D7
-  XK_Georgian_in == 0x000015D8
-  XK_Georgian_kan == 0x000015D9
-  XK_Georgian_las == 0x000015DA
-  XK_Georgian_man == 0x000015DB
-  XK_Georgian_nar == 0x000015DC
-  XK_Georgian_on == 0x000015DD
-  XK_Georgian_par == 0x000015DE
-  XK_Georgian_zhar == 0x000015DF
-  XK_Georgian_rae == 0x000015E0
-  XK_Georgian_san == 0x000015E1
-  XK_Georgian_tar == 0x000015E2
-  XK_Georgian_un == 0x000015E3
-  XK_Georgian_phar == 0x000015E4
-  XK_Georgian_khar == 0x000015E5
-  XK_Georgian_ghan == 0x000015E6
-  XK_Georgian_qar == 0x000015E7
-  XK_Georgian_shin == 0x000015E8
-  XK_Georgian_chin == 0x000015E9
-  XK_Georgian_can == 0x000015EA
-  XK_Georgian_jil == 0x000015EB
-  XK_Georgian_cil == 0x000015EC
-  XK_Georgian_char == 0x000015ED
-  XK_Georgian_xan == 0x000015EE
-  XK_Georgian_jhan == 0x000015EF
-  XK_Georgian_hae == 0x000015F0
-  XK_Georgian_he == 0x000015F1
-  XK_Georgian_hie == 0x000015F2
-  XK_Georgian_we == 0x000015F3
-  XK_Georgian_har == 0x000015F4
-  XK_Georgian_hoe == 0x000015F5
-  XK_Georgian_fi == 0x000015F6
-# XK_GEORGIAN 
-#*
-# * Azeri (and other Turkic or Caucasian languages of ex-USSR)
-# * Byte 3 = = $16
-# *
-
-when defined(XK_CAUCASUS): 
-  # latin 
-  XKc_Ccedillaabovedot == 0x000016A2
-  XKc_Xabovedot == 0x000016A3
-  XKc_Qabovedot == 0x000016A5
-  XKc_Ibreve == 0x000016A6
-  XKc_IE == 0x000016A7
-  XKc_UO == 0x000016A8
-  XKc_Zstroke == 0x000016A9
-  XKc_Gcaron == 0x000016AA
-  XKc_Obarred == 0x000016AF
-  XK_ccedillaabovedot == 0x000016B2
-  XK_xabovedot == 0x000016B3
-  XKc_Ocaron == 0x000016B4
-  XK_qabovedot == 0x000016B5
-  XK_ibreve == 0x000016B6
-  XK_ie == 0x000016B7
-  XK_uo == 0x000016B8
-  XK_zstroke == 0x000016B9
-  XK_gcaron == 0x000016BA
-  XK_ocaron == 0x000016BD
-  XK_obarred == 0x000016BF
-  XKc_SCHWA == 0x000016C6
-  XK_schwa == 0x000016F6 # those are not really Caucasus, but I put them here for now 
-                         # For Inupiak 
-  XKc_Lbelowdot == 0x000016D1
-  XKc_Lstrokebelowdot == 0x000016D2
-  XK_lbelowdot == 0x000016E1
-  XK_lstrokebelowdot == 0x000016E2 # For Guarani 
-  XKc_Gtilde == 0x000016D3
-  XK_gtilde == 0x000016E3
-# XK_CAUCASUS 
-#*
-# *   Vietnamese
-# *   Byte 3 = = $1e
-# *
-
-when defined(XK_VIETNAMESE): 
-  XKc_Abelowdot == 0x00001EA0
-  XK_abelowdot == 0x00001EA1
-  XKc_Ahook == 0x00001EA2
-  XK_ahook == 0x00001EA3
-  XKc_Acircumflexacute == 0x00001EA4
-  XK_acircumflexacute == 0x00001EA5
-  XKc_Acircumflexgrave == 0x00001EA6
-  XK_acircumflexgrave == 0x00001EA7
-  XKc_Acircumflexhook == 0x00001EA8
-  XK_acircumflexhook == 0x00001EA9
-  XKc_Acircumflextilde == 0x00001EAA
-  XK_acircumflextilde == 0x00001EAB
-  XKc_Acircumflexbelowdot == 0x00001EAC
-  XK_acircumflexbelowdot == 0x00001EAD
-  XKc_Abreveacute == 0x00001EAE
-  XK_abreveacute == 0x00001EAF
-  XKc_Abrevegrave == 0x00001EB0
-  XK_abrevegrave == 0x00001EB1
-  XKc_Abrevehook == 0x00001EB2
-  XK_abrevehook == 0x00001EB3
-  XKc_Abrevetilde == 0x00001EB4
-  XK_abrevetilde == 0x00001EB5
-  XKc_Abrevebelowdot == 0x00001EB6
-  XK_abrevebelowdot == 0x00001EB7
-  XKc_Ebelowdot == 0x00001EB8
-  XK_ebelowdot == 0x00001EB9
-  XKc_Ehook == 0x00001EBA
-  XK_ehook == 0x00001EBB
-  XKc_Etilde == 0x00001EBC
-  XK_etilde == 0x00001EBD
-  XKc_Ecircumflexacute == 0x00001EBE
-  XK_ecircumflexacute == 0x00001EBF
-  XKc_Ecircumflexgrave == 0x00001EC0
-  XK_ecircumflexgrave == 0x00001EC1
-  XKc_Ecircumflexhook == 0x00001EC2
-  XK_ecircumflexhook == 0x00001EC3
-  XKc_Ecircumflextilde == 0x00001EC4
-  XK_ecircumflextilde == 0x00001EC5
-  XKc_Ecircumflexbelowdot == 0x00001EC6
-  XK_ecircumflexbelowdot == 0x00001EC7
-  XKc_Ihook == 0x00001EC8
-  XK_ihook == 0x00001EC9
-  XKc_Ibelowdot == 0x00001ECA
-  XK_ibelowdot == 0x00001ECB
-  XKc_Obelowdot == 0x00001ECC
-  XK_obelowdot == 0x00001ECD
-  XKc_Ohook == 0x00001ECE
-  XK_ohook == 0x00001ECF
-  XKc_Ocircumflexacute == 0x00001ED0
-  XK_ocircumflexacute == 0x00001ED1
-  XKc_Ocircumflexgrave == 0x00001ED2
-  XK_ocircumflexgrave == 0x00001ED3
-  XKc_Ocircumflexhook == 0x00001ED4
-  XK_ocircumflexhook == 0x00001ED5
-  XKc_Ocircumflextilde == 0x00001ED6
-  XK_ocircumflextilde == 0x00001ED7
-  XKc_Ocircumflexbelowdot == 0x00001ED8
-  XK_ocircumflexbelowdot == 0x00001ED9
-  XKc_Ohornacute == 0x00001EDA
-  XK_ohornacute == 0x00001EDB
-  XKc_Ohorngrave == 0x00001EDC
-  XK_ohorngrave == 0x00001EDD
-  XKc_Ohornhook == 0x00001EDE
-  XK_ohornhook == 0x00001EDF
-  XKc_Ohorntilde == 0x00001EE0
-  XK_ohorntilde == 0x00001EE1
-  XKc_Ohornbelowdot == 0x00001EE2
-  XK_ohornbelowdot == 0x00001EE3
-  XKc_Ubelowdot == 0x00001EE4
-  XK_ubelowdot == 0x00001EE5
-  XKc_Uhook == 0x00001EE6
-  XK_uhook == 0x00001EE7
-  XKc_Uhornacute == 0x00001EE8
-  XK_uhornacute == 0x00001EE9
-  XKc_Uhorngrave == 0x00001EEA
-  XK_uhorngrave == 0x00001EEB
-  XKc_Uhornhook == 0x00001EEC
-  XK_uhornhook == 0x00001EED
-  XKc_Uhorntilde == 0x00001EEE
-  XK_uhorntilde == 0x00001EEF
-  XKc_Uhornbelowdot == 0x00001EF0
-  XK_uhornbelowdot == 0x00001EF1
-  XKc_Ybelowdot == 0x00001EF4
-  XK_ybelowdot == 0x00001EF5
-  XKc_Yhook == 0x00001EF6
-  XK_yhook == 0x00001EF7
-  XKc_Ytilde == 0x00001EF8
-  XK_ytilde == 0x00001EF9
-  XKc_Ohorn == 0x00001EFA     # U+01a0 
-  XK_ohorn == 0x00001EFB      # U+01a1 
-  XKc_Uhorn == 0x00001EFC     # U+01af 
-  XK_uhorn == 0x00001EFD      # U+01b0 
-  XK_combining_tilde == 0x00001E9F # U+0303 
-  XK_combining_grave == 0x00001EF2 # U+0300 
-  XK_combining_acute == 0x00001EF3 # U+0301 
-  XK_combining_hook == 0x00001EFE # U+0309 
-  XK_combining_belowdot == 0x00001EFF # U+0323 
-# XK_VIETNAMESE 
-
-when defined(XK_CURRENCY): 
-  XK_EcuSign == 0x000020A0
-  XK_ColonSign == 0x000020A1
-  XK_CruzeiroSign == 0x000020A2
-  XK_FFrancSign == 0x000020A3
-  XK_LiraSign == 0x000020A4
-  XK_MillSign == 0x000020A5
-  XK_NairaSign == 0x000020A6
-  XK_PesetaSign == 0x000020A7
-  XK_RupeeSign == 0x000020A8
-  XK_WonSign == 0x000020A9
-  XK_NewSheqelSign == 0x000020AA
-  XK_DongSign == 0x000020AB
-  XK_EuroSign == 0x000020AC
-# implementation
diff --git a/lib/contnrs.nim b/lib/contnrs.nim
deleted file mode 100644
index fa993e104..000000000
--- a/lib/contnrs.nim
+++ /dev/null
@@ -1,11 +0,0 @@
-# Container library for Nimrod
-
-# Data structures for now:
-# TTable, TSet, TList
-# Algorithms: Trees, hashing,
-
-TTable[key, val, [Algorithm]]
-
-macro TTable(n: typeexpr): typeexpr =
-
-
diff --git a/lib/dlmalloc.c b/lib/dlmalloc.c
deleted file mode 100644
index 2a8b299a1..000000000
--- a/lib/dlmalloc.c
+++ /dev/null
@@ -1,5076 +0,0 @@
-
-#define USE_DL_PREFIX
-#define ASSEMBLY_VERSION
-
-/*
-#define FOOTERS 1
-#define DEBUG 1
-
-#define ABORT_ON_ASSERT_FAILURE 0
-*/
-
-#define ABORT do { /*printf("abort was called\n");*/ abort(); } while (0)
-
-/*
-  This is a version (aka dlmalloc) of malloc/free/realloc written by
-  Doug Lea and released to the public domain, as explained at
-  http://creativecommons.org/licenses/publicdomain.  Send questions,
-  comments, complaints, performance data, etc to dl@cs.oswego.edu
-
-* Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)
-
-   Note: There may be an updated version of this malloc obtainable at
-           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
-         Check before installing!
-
-* Quickstart
-
-  This library is all in one file to simplify the most common usage:
-  ftp it, compile it (-O3), and link it into another program. All of
-  the compile-time options default to reasonable values for use on
-  most platforms.  You might later want to step through various
-  compile-time and dynamic tuning options.
-
-  For convenience, an include file for code using this malloc is at:
-     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h
-  You don't really need this .h file unless you call functions not
-  defined in your system include files.  The .h file contains only the
-  excerpts from this file needed for using this malloc on ANSI C/C++
-  systems, so long as you haven't changed compile-time options about
-  naming and tuning parameters.  If you do, then you can create your
-  own malloc.h that does include all settings by cutting at the point
-  indicated below. Note that you may already by default be using a C
-  library containing a malloc that is based on some version of this
-  malloc (for example in linux). You might still want to use the one
-  in this file to customize settings or to avoid overheads associated
-  with library versions.
-
-* Vital statistics:
-
-  Supported pointer/size_t representation:       4 or 8 bytes
-       size_t MUST be an unsigned type of the same width as
-       pointers. (If you are using an ancient system that declares
-       size_t as a signed type, or need it to be a different width
-       than pointers, you can use a previous release of this malloc
-       (e.g. 2.7.2) supporting these.)
-
-  Alignment:                                     8 bytes (default)
-       This suffices for nearly all current machines and C compilers.
-       However, you can define MALLOC_ALIGNMENT to be wider than this
-       if necessary (up to 128bytes), at the expense of using more space.
-
-  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
-                                          8 or 16 bytes (if 8byte sizes)
-       Each malloced chunk has a hidden word of overhead holding size
-       and status information, and additional cross-check word
-       if FOOTERS is defined.
-
-  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
-                          8-byte ptrs:  32 bytes    (including overhead)
-
-       Even a request for zero bytes (i.e., malloc(0)) returns a
-       pointer to something of the minimum allocatable size.
-       The maximum overhead wastage (i.e., number of extra bytes
-       allocated than were requested in malloc) is less than or equal
-       to the minimum size, except for requests >= mmap_threshold that
-       are serviced via mmap(), where the worst case wastage is about
-       32 bytes plus the remainder from a system page (the minimal
-       mmap unit); typically 4096 or 8192 bytes.
-
-  Security: static-safe; optionally more or less
-       The "security" of malloc refers to the ability of malicious
-       code to accentuate the effects of errors (for example, freeing
-       space that is not currently malloc'ed or overwriting past the
-       ends of chunks) in code that calls malloc.  This malloc
-       guarantees not to modify any memory locations below the base of
-       heap, i.e., static variables, even in the presence of usage
-       errors.  The routines additionally detect most improper frees
-       and reallocs.  All this holds as long as the static bookkeeping
-       for malloc itself is not corrupted by some other means.  This
-       is only one aspect of security -- these checks do not, and
-       cannot, detect all possible programming errors.
-
-       If FOOTERS is defined nonzero, then each allocated chunk
-       carries an additional check word to verify that it was malloced
-       from its space.  These check words are the same within each
-       execution of a program using malloc, but differ across
-       executions, so externally crafted fake chunks cannot be
-       freed. This improves security by rejecting frees/reallocs that
-       could corrupt heap memory, in addition to the checks preventing
-       writes to statics that are always on.  This may further improve
-       security at the expense of time and space overhead.  (Note that
-       FOOTERS may also be worth using with MSPACES.)
-
-       By default detected errors cause the program to abort (calling
-       "abort()"). You can override this to instead proceed past
-       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
-       has no effect, and a malloc that encounters a bad address
-       caused by user overwrites will ignore the bad address by
-       dropping pointers and indices to all known memory. This may
-       be appropriate for programs that should continue if at all
-       possible in the face of programming errors, although they may
-       run out of memory because dropped memory is never reclaimed.
-
-       If you don't like either of these options, you can define
-       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
-       else. And if if you are sure that your program using malloc has
-       no errors or vulnerabilities, you can define INSECURE to 1,
-       which might (or might not) provide a small performance improvement.
-
-  Thread-safety: NOT thread-safe unless USE_LOCKS defined
-       When USE_LOCKS is defined, each public call to malloc, free,
-       etc is surrounded with either a pthread mutex or a win32
-       spinlock (depending on WIN32). This is not especially fast, and
-       can be a major bottleneck.  It is designed only to provide
-       minimal protection in concurrent environments, and to provide a
-       basis for extensions.  If you are using malloc in a concurrent
-       program, consider instead using ptmalloc, which is derived from
-       a version of this malloc. (See http://www.malloc.de).
-
-  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
-       This malloc can use unix sbrk or any emulation (invoked using
-       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
-       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
-       memory.  On most unix systems, it tends to work best if both
-       MORECORE and MMAP are enabled.  On Win32, it uses emulations
-       based on VirtualAlloc. It also uses common C library functions
-       like memset.
-
-  Compliance: I believe it is compliant with the Single Unix Specification
-       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
-       others as well.
-
-* Overview of algorithms
-
-  This is not the fastest, most space-conserving, most portable, or
-  most tunable malloc ever written. However it is among the fastest
-  while also being among the most space-conserving, portable and
-  tunable.  Consistent balance across these factors results in a good
-  general-purpose allocator for malloc-intensive programs.
-
-  In most ways, this malloc is a best-fit allocator. Generally, it
-  chooses the best-fitting existing chunk for a request, with ties
-  broken in approximately least-recently-used order. (This strategy
-  normally maintains low fragmentation.) However, for requests less
-  than 256bytes, it deviates from best-fit when there is not an
-  exactly fitting available chunk by preferring to use space adjacent
-  to that used for the previous small request, as well as by breaking
-  ties in approximately most-recently-used order. (These enhance
-  locality of series of small allocations.)  And for very large requests
-  (>= 256Kb by default), it relies on system memory mapping
-  facilities, if supported.  (This helps avoid carrying around and
-  possibly fragmenting memory used only for large chunks.)
-
-  All operations (except malloc_stats and mallinfo) have execution
-  times that are bounded by a constant factor of the number of bits in
-  a size_t, not counting any clearing in calloc or copying in realloc,
-  or actions surrounding MORECORE and MMAP that have times
-  proportional to the number of non-contiguous regions returned by
-  system allocation routines, which is often just 1.
-
-  The implementation is not very modular and seriously overuses
-  macros. Perhaps someday all C compilers will do as good a job
-  inlining modular code as can now be done by brute-force expansion,
-  but now, enough of them seem not to.
-
-  Some compilers issue a lot of warnings about code that is
-  dead/unreachable only on some platforms, and also about intentional
-  uses of negation on unsigned types. All known cases of each can be
-  ignored.
-
-  For a longer but out of date high-level description, see
-     http://gee.cs.oswego.edu/dl/html/malloc.html
-
-* MSPACES
-  If MSPACES is defined, then in addition to malloc, free, etc.,
-  this file also defines mspace_malloc, mspace_free, etc. These
-  are versions of malloc routines that take an "mspace" argument
-  obtained using create_mspace, to control all internal bookkeeping.
-  If ONLY_MSPACES is defined, only these versions are compiled.
-  So if you would like to use this allocator for only some allocations,
-  and your system malloc for others, you can compile with
-  ONLY_MSPACES and then do something like...
-    static mspace mymspace = create_mspace(0,0); // for example
-    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
-
-  (Note: If you only need one instance of an mspace, you can instead
-  use "USE_DL_PREFIX" to relabel the global malloc.)
-
-  You can similarly create thread-local allocators by storing
-  mspaces as thread-locals. For example:
-    static __thread mspace tlms = 0;
-    void*  tlmalloc(size_t bytes) {
-      if (tlms == 0) tlms = create_mspace(0, 0);
-      return mspace_malloc(tlms, bytes);
-    }
-    void  tlfree(void* mem) { mspace_free(tlms, mem); }
-
-  Unless FOOTERS is defined, each mspace is completely independent.
-  You cannot allocate from one and free to another (although
-  conformance is only weakly checked, so usage errors are not always
-  caught). If FOOTERS is defined, then each chunk carries around a tag
-  indicating its originating mspace, and frees are directed to their
-  originating spaces.
-
- -------------------------  Compile-time options ---------------------------
-
-Be careful in setting #define values for numerical constants of type
-size_t. On some systems, literal values are not automatically extended
-to size_t precision unless they are explicitly casted.
-
-WIN32                    default: defined if _WIN32 defined
-  Defining WIN32 sets up defaults for MS environment and compilers.
-  Otherwise defaults are for unix.
-
-MALLOC_ALIGNMENT         default: (size_t)8
-  Controls the minimum alignment for malloc'ed chunks.  It must be a
-  power of two and at least 8, even on machines for which smaller
-  alignments would suffice. It may be defined as larger than this
-  though. Note however that code and data structures are optimized for
-  the case of 8-byte alignment.
-
-MSPACES                  default: 0 (false)
-  If true, compile in support for independent allocation spaces.
-  This is only supported if HAVE_MMAP is true.
-
-ONLY_MSPACES             default: 0 (false)
-  If true, only compile in mspace versions, not regular versions.
-
-USE_LOCKS                default: 0 (false)
-  Causes each call to each public routine to be surrounded with
-  pthread or WIN32 mutex lock/unlock. (If set true, this can be
-  overridden on a per-mspace basis for mspace versions.)
-
-FOOTERS                  default: 0
-  If true, provide extra checking and dispatching by placing
-  information in the footers of allocated chunks. This adds
-  space and time overhead.
-
-INSECURE                 default: 0
-  If true, omit checks for usage errors and heap space overwrites.
-
-USE_DL_PREFIX            default: NOT defined
-  Causes compiler to prefix all public routines with the string 'dl'.
-  This can be useful when you only want to use this malloc in one part
-  of a program, using your regular system malloc elsewhere.
-
-ABORT                    default: defined as abort()
-  Defines how to abort on failed checks.  On most systems, a failed
-  check cannot die with an "assert" or even print an informative
-  message, because the underlying print routines in turn call malloc,
-  which will fail again.  Generally, the best policy is to simply call
-  abort(). It's not very useful to do more than this because many
-  errors due to overwriting will show up as address faults (null, odd
-  addresses etc) rather than malloc-triggered checks, so will also
-  abort.  Also, most compilers know that abort() does not return, so
-  can better optimize code conditionally calling it.
-
-PROCEED_ON_ERROR           default: defined as 0 (false)
-  Controls whether detected bad addresses cause them to bypassed
-  rather than aborting. If set, detected bad arguments to free and
-  realloc are ignored. And all bookkeeping information is zeroed out
-  upon a detected overwrite of freed heap space, thus losing the
-  ability to ever return it from malloc again, but enabling the
-  application to proceed. If PROCEED_ON_ERROR is defined, the
-  static variable malloc_corruption_error_count is compiled in
-  and can be examined to see if errors have occurred. This option
-  generates slower code than the default abort policy.
-
-DEBUG                    default: NOT defined
-  The DEBUG setting is mainly intended for people trying to modify
-  this code or diagnose problems when porting to new platforms.
-  However, it may also be able to better isolate user errors than just
-  using runtime checks.  The assertions in the check routines spell
-  out in more detail the assumptions and invariants underlying the
-  algorithms.  The checking is fairly extensive, and will slow down
-  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
-  set will attempt to check every non-mmapped allocated and free chunk
-  in the course of computing the summaries.
-
-ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
-  Debugging assertion failures can be nearly impossible if your
-  version of the assert macro causes malloc to be called, which will
-  lead to a cascade of further failures, blowing the runtime stack.
-  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
-  which will usually make debugging easier.
-
-MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
-  The action to take before "return 0" when malloc fails to be able to
-  return memory because there is none available.
-
-HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
-  True if this system supports sbrk or an emulation of it.
-
-MORECORE                  default: sbrk
-  The name of the sbrk-style system routine to call to obtain more
-  memory.  See below for guidance on writing custom MORECORE
-  functions. The type of the argument to sbrk/MORECORE varies across
-  systems.  It cannot be size_t, because it supports negative
-  arguments, so it is normally the signed type of the same width as
-  size_t (sometimes declared as "intptr_t").  It doesn't much matter
-  though. Internally, we only call it with arguments less than half
-  the max value of a size_t, which should work across all reasonable
-  possibilities, although sometimes generating compiler warnings.  See
-  near the end of this file for guidelines for creating a custom
-  version of MORECORE.
-
-MORECORE_CONTIGUOUS       default: 1 (true)
-  If true, take advantage of fact that consecutive calls to MORECORE
-  with positive arguments always return contiguous increasing
-  addresses.  This is true of unix sbrk. It does not hurt too much to
-  set it true anyway, since malloc copes with non-contiguities.
-  Setting it false when definitely non-contiguous saves time
-  and possibly wasted space it would take to discover this though.
-
-MORECORE_CANNOT_TRIM      default: NOT defined
-  True if MORECORE cannot release space back to the system when given
-  negative arguments. This is generally necessary only if you are
-  using a hand-crafted MORECORE function that cannot handle negative
-  arguments.
-
-HAVE_MMAP                 default: 1 (true)
-  True if this system supports mmap or an emulation of it.  If so, and
-  HAVE_MORECORE is not true, MMAP is used for all system
-  allocation. If set and HAVE_MORECORE is true as well, MMAP is
-  primarily used to directly allocate very large blocks. It is also
-  used as a backup strategy in cases where MORECORE fails to provide
-  space from system. Note: A single call to MUNMAP is assumed to be
-  able to unmap memory that may have be allocated using multiple calls
-  to MMAP, so long as they are adjacent.
-
-HAVE_MREMAP               default: 1 on linux, else 0
-  If true realloc() uses mremap() to re-allocate large blocks and
-  extend or shrink allocation spaces.
-
-MMAP_CLEARS               default: 1 on unix
-  True if mmap clears memory so calloc doesn't need to. This is true
-  for standard unix mmap using /dev/zero.
-
-USE_BUILTIN_FFS            default: 0 (i.e., not used)
-  Causes malloc to use the builtin ffs() function to compute indices.
-  Some compilers may recognize and intrinsify ffs to be faster than the
-  supplied C version. Also, the case of x86 using gcc is special-cased
-  to an asm instruction, so is already as fast as it can be, and so
-  this setting has no effect. (On most x86s, the asm version is only
-  slightly faster than the C version.)
-
-malloc_getpagesize         default: derive from system includes, or 4096.
-  The system page size. To the extent possible, this malloc manages
-  memory from the system in page-size units.  This may be (and
-  usually is) a function rather than a constant. This is ignored
-  if WIN32, where page size is determined using getSystemInfo during
-  initialization.
-
-USE_DEV_RANDOM             default: 0 (i.e., not used)
-  Causes malloc to use /dev/random to initialize secure magic seed for
-  stamping footers. Otherwise, the current time is used.
-
-NO_MALLINFO                default: 0
-  If defined, don't compile "mallinfo". This can be a simple way
-  of dealing with mismatches between system declarations and
-  those in this file.
-
-MALLINFO_FIELD_TYPE        default: size_t
-  The type of the fields in the mallinfo struct. This was originally
-  defined as "int" in SVID etc, but is more usefully defined as
-  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
-
-REALLOC_ZERO_BYTES_FREES    default: not defined
-  This should be set if a call to realloc with zero bytes should
-  be the same as a call to free. Some people think it should. Otherwise,
-  since this malloc returns a unique pointer for malloc(0), so does
-  realloc(p, 0).
-
-LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
-LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
-LACKS_STDLIB_H                default: NOT defined unless on WIN32
-  Define these if your system does not have these header files.
-  You might need to manually insert some of the declarations they provide.
-
-DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
-                                system_info.dwAllocationGranularity in WIN32,
-                                otherwise 64K.
-      Also settable using mallopt(M_GRANULARITY, x)
-  The unit for allocating and deallocating memory from the system.  On
-  most systems with contiguous MORECORE, there is no reason to
-  make this more than a page. However, systems with MMAP tend to
-  either require or encourage larger granularities.  You can increase
-  this value to prevent system allocation functions to be called so
-  often, especially if they are slow.  The value must be at least one
-  page and must be a power of two.  Setting to 0 causes initialization
-  to either page size or win32 region size.  (Note: In previous
-  versions of malloc, the equivalent of this option was called
-  "TOP_PAD")
-
-DEFAULT_TRIM_THRESHOLD    default: 2MB
-      Also settable using mallopt(M_TRIM_THRESHOLD, x)
-  The maximum amount of unused top-most memory to keep before
-  releasing via malloc_trim in free().  Automatic trimming is mainly
-  useful in long-lived programs using contiguous MORECORE.  Because
-  trimming via sbrk can be slow on some systems, and can sometimes be
-  wasteful (in cases where programs immediately afterward allocate
-  more large chunks) the value should be high enough so that your
-  overall system performance would improve by releasing this much
-  memory.  As a rough guide, you might set to a value close to the
-  average size of a process (program) running on your system.
-  Releasing this much memory would allow such a process to run in
-  memory.  Generally, it is worth tuning trim thresholds when a
-  program undergoes phases where several large chunks are allocated
-  and released in ways that can reuse each other's storage, perhaps
-  mixed with phases where there are no such chunks at all. The trim
-  value must be greater than page size to have any useful effect.  To
-  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
-  some people use of mallocing a huge space and then freeing it at
-  program startup, in an attempt to reserve system memory, doesn't
-  have the intended effect under automatic trimming, since that memory
-  will immediately be returned to the system.
-
-DEFAULT_MMAP_THRESHOLD       default: 256K
-      Also settable using mallopt(M_MMAP_THRESHOLD, x)
-  The request size threshold for using MMAP to directly service a
-  request. Requests of at least this size that cannot be allocated
-  using already-existing space will be serviced via mmap.  (If enough
-  normal freed space already exists it is used instead.)  Using mmap
-  segregates relatively large chunks of memory so that they can be
-  individually obtained and released from the host system. A request
-  serviced through mmap is never reused by any other request (at least
-  not directly; the system may just so happen to remap successive
-  requests to the same locations).  Segregating space in this way has
-  the benefits that: Mmapped space can always be individually released
-  back to the system, which helps keep the system level memory demands
-  of a long-lived program low.  Also, mapped memory doesn't become
-  `locked' between other chunks, as can happen with normally allocated
-  chunks, which means that even trimming via malloc_trim would not
-  release them.  However, it has the disadvantage that the space
-  cannot be reclaimed, consolidated, and then used to service later
-  requests, as happens with normal chunks.  The advantages of mmap
-  nearly always outweigh disadvantages for "large" chunks, but the
-  value of "large" may vary across systems.  The default is an
-  empirically derived value that works well in most systems. You can
-  disable mmap by setting to MAX_SIZE_T.
-
-*/
-#if defined(__WATCOMC__) || defined(_MSC_VER)
-#define WIN32 1
-#endif
-
-#ifndef WIN32
-#ifdef _WIN32
-#define WIN32 1
-#endif  /* _WIN32 */
-#endif  /* WIN32 */
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#define HAVE_MORECORE 0
-#define LACKS_UNISTD_H
-#define LACKS_SYS_PARAM_H
-#define LACKS_SYS_MMAN_H
-#define LACKS_STRING_H
-#define LACKS_STRINGS_H
-#define LACKS_SYS_TYPES_H
-#define LACKS_ERRNO_H
-#define MALLOC_FAILURE_ACTION
-#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */
-#endif  /* WIN32 */
-
-#if defined(DARWIN) || defined(_DARWIN)
-/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
-#ifndef HAVE_MORECORE
-#define HAVE_MORECORE 0
-#define HAVE_MMAP 1
-#endif  /* HAVE_MORECORE */
-#endif  /* DARWIN */
-
-#ifndef LACKS_SYS_TYPES_H
-#include <sys/types.h>  /* For size_t */
-#endif  /* LACKS_SYS_TYPES_H */
-
-/* The maximum possible size_t value has all bits set */
-#define MAX_SIZE_T           (~(size_t)0)
-
-#ifndef ONLY_MSPACES
-#define ONLY_MSPACES 0
-#endif  /* ONLY_MSPACES */
-#ifndef MSPACES
-#if ONLY_MSPACES
-#define MSPACES 1
-#else   /* ONLY_MSPACES */
-#define MSPACES 0
-#endif  /* ONLY_MSPACES */
-#endif  /* MSPACES */
-#ifndef MALLOC_ALIGNMENT
-#define MALLOC_ALIGNMENT ((size_t)8U)
-#endif  /* MALLOC_ALIGNMENT */
-#ifndef FOOTERS
-#define FOOTERS 0
-#endif  /* FOOTERS */
-#ifndef ABORT
-#define ABORT  abort()
-#endif  /* ABORT */
-#ifndef ABORT_ON_ASSERT_FAILURE
-#define ABORT_ON_ASSERT_FAILURE 1
-#endif  /* ABORT_ON_ASSERT_FAILURE */
-#ifndef PROCEED_ON_ERROR
-#define PROCEED_ON_ERROR 0
-#endif  /* PROCEED_ON_ERROR */
-#ifndef USE_LOCKS
-#define USE_LOCKS 0
-#endif  /* USE_LOCKS */
-#ifndef INSECURE
-#define INSECURE 0
-#endif  /* INSECURE */
-#ifndef HAVE_MMAP
-#define HAVE_MMAP 1
-#endif  /* HAVE_MMAP */
-#ifndef MMAP_CLEARS
-#define MMAP_CLEARS 1
-#endif  /* MMAP_CLEARS */
-#ifndef HAVE_MREMAP
-#ifdef linux
-#define HAVE_MREMAP 1
-#else   /* linux */
-#define HAVE_MREMAP 0
-#endif  /* linux */
-#endif  /* HAVE_MREMAP */
-#ifndef MALLOC_FAILURE_ACTION
-#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
-#endif  /* MALLOC_FAILURE_ACTION */
-#ifndef HAVE_MORECORE
-#if ONLY_MSPACES
-#define HAVE_MORECORE 0
-#else   /* ONLY_MSPACES */
-#define HAVE_MORECORE 1
-#endif  /* ONLY_MSPACES */
-#endif  /* HAVE_MORECORE */
-#if !HAVE_MORECORE
-#define MORECORE_CONTIGUOUS 0
-#else   /* !HAVE_MORECORE */
-#ifndef MORECORE
-#define MORECORE sbrk
-#endif  /* MORECORE */
-#ifndef MORECORE_CONTIGUOUS
-#define MORECORE_CONTIGUOUS 1
-#endif  /* MORECORE_CONTIGUOUS */
-#endif  /* HAVE_MORECORE */
-#ifndef DEFAULT_GRANULARITY
-#if MORECORE_CONTIGUOUS
-#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
-#else   /* MORECORE_CONTIGUOUS */
-#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
-#endif  /* MORECORE_CONTIGUOUS */
-#endif  /* DEFAULT_GRANULARITY */
-#ifndef DEFAULT_TRIM_THRESHOLD
-#ifndef MORECORE_CANNOT_TRIM
-#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
-#else   /* MORECORE_CANNOT_TRIM */
-#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
-#endif  /* MORECORE_CANNOT_TRIM */
-#endif  /* DEFAULT_TRIM_THRESHOLD */
-#ifndef DEFAULT_MMAP_THRESHOLD
-#if HAVE_MMAP
-#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
-#else   /* HAVE_MMAP */
-#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
-#endif  /* HAVE_MMAP */
-#endif  /* DEFAULT_MMAP_THRESHOLD */
-#ifndef USE_BUILTIN_FFS
-#define USE_BUILTIN_FFS 0
-#endif  /* USE_BUILTIN_FFS */
-#ifndef USE_DEV_RANDOM
-#define USE_DEV_RANDOM 0
-#endif  /* USE_DEV_RANDOM */
-#ifndef NO_MALLINFO
-#define NO_MALLINFO 0
-#endif  /* NO_MALLINFO */
-#ifndef MALLINFO_FIELD_TYPE
-#define MALLINFO_FIELD_TYPE size_t
-#endif  /* MALLINFO_FIELD_TYPE */
-
-/*
-  mallopt tuning options.  SVID/XPG defines four standard parameter
-  numbers for mallopt, normally defined in malloc.h.  None of these
-  are used in this malloc, so setting them has no effect. But this
-  malloc does support the following options.
-*/
-
-#define M_TRIM_THRESHOLD     (-1)
-#define M_GRANULARITY        (-2)
-#define M_MMAP_THRESHOLD     (-3)
-
-/* ------------------------ Mallinfo declarations ------------------------ */
-
-#if !NO_MALLINFO
-/*
-  This version of malloc supports the standard SVID/XPG mallinfo
-  routine that returns a struct containing usage properties and
-  statistics. It should work on any system that has a
-  /usr/include/malloc.h defining struct mallinfo.  The main
-  declaration needed is the mallinfo struct that is returned (by-copy)
-  by mallinfo().  The malloinfo struct contains a bunch of fields that
-  are not even meaningful in this version of malloc.  These fields are
-  are instead filled by mallinfo() with other numbers that might be of
-  interest.
-
-  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
-  /usr/include/malloc.h file that includes a declaration of struct
-  mallinfo.  If so, it is included; else a compliant version is
-  declared below.  These must be precisely the same for mallinfo() to
-  work.  The original SVID version of this struct, defined on most
-  systems with mallinfo, declares all fields as ints. But some others
-  define as unsigned long. If your system defines the fields using a
-  type of different width than listed here, you MUST #include your
-  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
-*/
-
-/* #define HAVE_USR_INCLUDE_MALLOC_H */
-
-#ifdef HAVE_USR_INCLUDE_MALLOC_H
-#include "/usr/include/malloc.h"
-#else /* HAVE_USR_INCLUDE_MALLOC_H */
-
-struct mallinfo {
-  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
-  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
-  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
-  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
-  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
-  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
-  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
-  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
-  MALLINFO_FIELD_TYPE fordblks; /* total free space */
-  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
-};
-
-#endif /* HAVE_USR_INCLUDE_MALLOC_H */
-#endif /* NO_MALLINFO */
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#if !ONLY_MSPACES
-
-/* ------------------- Declarations of public routines ------------------- */
-
-#ifndef USE_DL_PREFIX
-#define dlcalloc               calloc
-#define dlfree                 free
-#define dlmalloc               malloc
-#define dlmemalign             memalign
-#define dlrealloc              realloc
-#define dlvalloc               valloc
-#define dlpvalloc              pvalloc
-#define dlmallinfo             mallinfo
-#define dlmallopt              mallopt
-#define dlmalloc_trim          malloc_trim
-#define dlmalloc_stats         malloc_stats
-#define dlmalloc_usable_size   malloc_usable_size
-#define dlmalloc_footprint     malloc_footprint
-#define dlmalloc_max_footprint malloc_max_footprint
-#define dlindependent_calloc   independent_calloc
-#define dlindependent_comalloc independent_comalloc
-#endif /* USE_DL_PREFIX */
-
-
-/*
-  malloc(size_t n)
-  Returns a pointer to a newly allocated chunk of at least n bytes, or
-  null if no space is available, in which case errno is set to ENOMEM
-  on ANSI C systems.
-
-  If n is zero, malloc returns a minimum-sized chunk. (The minimum
-  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
-  systems.)  Note that size_t is an unsigned type, so calls with
-  arguments that would be negative if signed are interpreted as
-  requests for huge amounts of space, which will often fail. The
-  maximum supported value of n differs across systems, but is in all
-  cases less than the maximum representable value of a size_t.
-*/
-void* dlmalloc(size_t);
-
-/*
-  free(void* p)
-  Releases the chunk of memory pointed to by p, that had been previously
-  allocated using malloc or a related routine such as realloc.
-  It has no effect if p is null. If p was not malloced or already
-  freed, free(p) will by default cause the current program to abort.
-*/
-void  dlfree(void*);
-
-/*
-  calloc(size_t n_elements, size_t element_size);
-  Returns a pointer to n_elements * element_size bytes, with all locations
-  set to zero.
-*/
-void* dlcalloc(size_t, size_t);
-
-/*
-  realloc(void* p, size_t n)
-  Returns a pointer to a chunk of size n that contains the same data
-  as does chunk p up to the minimum of (n, p's size) bytes, or null
-  if no space is available.
-
-  The returned pointer may or may not be the same as p. The algorithm
-  prefers extending p in most cases when possible, otherwise it
-  employs the equivalent of a malloc-copy-free sequence.
-
-  If p is null, realloc is equivalent to malloc.
-
-  If space is not available, realloc returns null, errno is set (if on
-  ANSI) and p is NOT freed.
-
-  if n is for fewer bytes than already held by p, the newly unused
-  space is lopped off and freed if possible.  realloc with a size
-  argument of zero (re)allocates a minimum-sized chunk.
-
-  The old unix realloc convention of allowing the last-free'd chunk
-  to be used as an argument to realloc is not supported.
-*/
-
-void* dlrealloc(void*, size_t);
-
-/*
-  memalign(size_t alignment, size_t n);
-  Returns a pointer to a newly allocated chunk of n bytes, aligned
-  in accord with the alignment argument.
-
-  The alignment argument should be a power of two. If the argument is
-  not a power of two, the nearest greater power is used.
-  8-byte alignment is guaranteed by normal malloc calls, so don't
-  bother calling memalign with an argument of 8 or less.
-
-  Overreliance on memalign is a sure way to fragment space.
-*/
-void* dlmemalign(size_t, size_t);
-
-/*
-  valloc(size_t n);
-  Equivalent to memalign(pagesize, n), where pagesize is the page
-  size of the system. If the pagesize is unknown, 4096 is used.
-*/
-void* dlvalloc(size_t);
-
-/*
-  mallopt(int parameter_number, int parameter_value)
-  Sets tunable parameters The format is to provide a
-  (parameter-number, parameter-value) pair.  mallopt then sets the
-  corresponding parameter to the argument value if it can (i.e., so
-  long as the value is meaningful), and returns 1 if successful else
-  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,
-  normally defined in malloc.h.  None of these are use in this malloc,
-  so setting them has no effect. But this malloc also supports other
-  options in mallopt. See below for details.  Briefly, supported
-  parameters are as follows (listed defaults are for "typical"
-  configurations).
-
-  Symbol            param #  default    allowed param values
-  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (MAX_SIZE_T disables)
-  M_GRANULARITY        -2     page size   any power of 2 >= page size
-  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
-*/
-int dlmallopt(int, int);
-
-/*
-  malloc_footprint();
-  Returns the number of bytes obtained from the system.  The total
-  number of bytes allocated by malloc, realloc etc., is less than this
-  value. Unlike mallinfo, this function returns only a precomputed
-  result, so can be called frequently to monitor memory consumption.
-  Even if locks are otherwise defined, this function does not use them,
-  so results might not be up to date.
-*/
-size_t dlmalloc_footprint(void);
-
-/*
-  malloc_max_footprint();
-  Returns the maximum number of bytes obtained from the system. This
-  value will be greater than current footprint if deallocated space
-  has been reclaimed by the system. The peak number of bytes allocated
-  by malloc, realloc etc., is less than this value. Unlike mallinfo,
-  this function returns only a precomputed result, so can be called
-  frequently to monitor memory consumption.  Even if locks are
-  otherwise defined, this function does not use them, so results might
-  not be up to date.
-*/
-size_t dlmalloc_max_footprint(void);
-
-#if !NO_MALLINFO
-/*
-  mallinfo()
-  Returns (by copy) a struct containing various summary statistics:
-
-  arena:     current total non-mmapped bytes allocated from system
-  ordblks:   the number of free chunks
-  smblks:    always zero.
-  hblks:     current number of mmapped regions
-  hblkhd:    total bytes held in mmapped regions
-  usmblks:   the maximum total allocated space. This will be greater
-                than current total if trimming has occurred.
-  fsmblks:   always zero
-  uordblks:  current total allocated space (normal or mmapped)
-  fordblks:  total free space
-  keepcost:  the maximum number of bytes that could ideally be released
-               back to system via malloc_trim. ("ideally" means that
-               it ignores page restrictions etc.)
-
-  Because these fields are ints, but internal bookkeeping may
-  be kept as longs, the reported values may wrap around zero and
-  thus be inaccurate.
-*/
-struct mallinfo dlmallinfo(void);
-#endif /* NO_MALLINFO */
-
-/*
-  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
-
-  independent_calloc is similar to calloc, but instead of returning a
-  single cleared space, it returns an array of pointers to n_elements
-  independent elements that can hold contents of size elem_size, each
-  of which starts out cleared, and can be independently freed,
-  realloc'ed etc. The elements are guaranteed to be adjacently
-  allocated (this is not guaranteed to occur with multiple callocs or
-  mallocs), which may also improve cache locality in some
-  applications.
-
-  The "chunks" argument is optional (i.e., may be null, which is
-  probably the most typical usage). If it is null, the returned array
-  is itself dynamically allocated and should also be freed when it is
-  no longer needed. Otherwise, the chunks array must be of at least
-  n_elements in length. It is filled in with the pointers to the
-  chunks.
-
-  In either case, independent_calloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and "chunks"
-  is null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be individually freed when it is no longer
-  needed. If you'd like to instead be able to free all at once, you
-  should instead use regular calloc and assign pointers into this
-  space to represent elements.  (In this case though, you cannot
-  independently free elements.)
-
-  independent_calloc simplifies and speeds up implementations of many
-  kinds of pools.  It may also be useful when constructing large data
-  structures that initially have a fixed number of fixed-sized nodes,
-  but the number is not known at compile time, and some of the nodes
-  may later need to be freed. For example:
-
-  struct Node { int item; struct Node* next; };
-
-  struct Node* build_list() {
-    struct Node** pool;
-    int n = read_number_of_nodes_needed();
-    if (n <= 0) return 0;
-    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
-    if (pool == 0) die();
-    // organize into a linked list...
-    struct Node* first = pool[0];
-    for (i = 0; i < n-1; ++i)
-      pool[i]->next = pool[i+1];
-    free(pool);     // Can now free the array (or not, if it is needed later)
-    return first;
-  }
-*/
-void** dlindependent_calloc(size_t, size_t, void**);
-
-/*
-  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
-
-  independent_comalloc allocates, all at once, a set of n_elements
-  chunks with sizes indicated in the "sizes" array.    It returns
-  an array of pointers to these elements, each of which can be
-  independently freed, realloc'ed etc. The elements are guaranteed to
-  be adjacently allocated (this is not guaranteed to occur with
-  multiple callocs or mallocs), which may also improve cache locality
-  in some applications.
-
-  The "chunks" argument is optional (i.e., may be null). If it is null
-  the returned array is itself dynamically allocated and should also
-  be freed when it is no longer needed. Otherwise, the chunks array
-  must be of at least n_elements in length. It is filled in with the
-  pointers to the chunks.
-
-  In either case, independent_comalloc returns this pointer array, or
-  null if the allocation failed.  If n_elements is zero and chunks is
-  null, it returns a chunk representing an array with zero elements
-  (which should be freed if not wanted).
-
-  Each element must be individually freed when it is no longer
-  needed. If you'd like to instead be able to free all at once, you
-  should instead use a single regular malloc, and assign pointers at
-  particular offsets in the aggregate space. (In this case though, you
-  cannot independently free elements.)
-
-  independent_comallac differs from independent_calloc in that each
-  element may have a different size, and also that it does not
-  automatically clear elements.
-
-  independent_comalloc can be used to speed up allocation in cases
-  where several structs or objects must always be allocated at the
-  same time.  For example:
-
-  struct Head { ... }
-  struct Foot { ... }
-
-  void send_message(char* msg) {
-    int msglen = strlen(msg);
-    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
-    void* chunks[3];
-    if (independent_comalloc(3, sizes, chunks) == 0)
-      die();
-    struct Head* head = (struct Head*)(chunks[0]);
-    char*        body = (char*)(chunks[1]);
-    struct Foot* foot = (struct Foot*)(chunks[2]);
-    // ...
-  }
-
-  In general though, independent_comalloc is worth using only for
-  larger values of n_elements. For small values, you probably won't
-  detect enough difference from series of malloc calls to bother.
-
-  Overuse of independent_comalloc can increase overall memory usage,
-  since it cannot reuse existing noncontiguous small chunks that
-  might be available for some of the elements.
-*/
-void** dlindependent_comalloc(size_t, size_t*, void**);
-
-
-/*
-  pvalloc(size_t n);
-  Equivalent to valloc(minimum-page-that-holds(n)), that is,
-  round up n to nearest pagesize.
- */
-void*  dlpvalloc(size_t);
-
-/*
-  malloc_trim(size_t pad);
-
-  If possible, gives memory back to the system (via negative arguments
-  to sbrk) if there is unused memory at the `high' end of the malloc
-  pool or in unused MMAP segments. You can call this after freeing
-  large blocks of memory to potentially reduce the system-level memory
-  requirements of a program. However, it cannot guarantee to reduce
-  memory. Under some allocation patterns, some large free blocks of
-  memory will be locked between two used chunks, so they cannot be
-  given back to the system.
-
-  The `pad' argument to malloc_trim represents the amount of free
-  trailing space to leave untrimmed. If this argument is zero, only
-  the minimum amount of memory to maintain internal data structures
-  will be left. Non-zero arguments can be supplied to maintain enough
-  trailing space to service future expected allocations without having
-  to re-obtain memory from the system.
-
-  Malloc_trim returns 1 if it actually released any memory, else 0.
-*/
-int  dlmalloc_trim(size_t);
-
-/*
-  malloc_usable_size(void* p);
-
-  Returns the number of bytes you can actually use in
-  an allocated chunk, which may be more than you requested (although
-  often not) due to alignment and minimum size constraints.
-  You can use this many bytes without worrying about
-  overwriting other allocated objects. This is not a particularly great
-  programming practice. malloc_usable_size can be more useful in
-  debugging and assertions, for example:
-
-  p = malloc(n);
-  assert(malloc_usable_size(p) >= 256);
-*/
-size_t dlmalloc_usable_size(void*);
-
-/*
-  malloc_stats();
-  Prints on stderr the amount of space obtained from the system (both
-  via sbrk and mmap), the maximum amount (which may be more than
-  current if malloc_trim and/or munmap got called), and the current
-  number of bytes allocated via malloc (or realloc, etc) but not yet
-  freed. Note that this is the number of bytes allocated, not the
-  number requested. It will be larger than the number requested
-  because of alignment and bookkeeping overhead. Because it includes
-  alignment wastage as being in use, this figure may be greater than
-  zero even when no user-level chunks are allocated.
-
-  The reported current and maximum system memory can be inaccurate if
-  a program makes other calls to system memory allocation functions
-  (normally sbrk) outside of malloc.
-
-  malloc_stats prints only the most commonly interesting statistics.
-  More information can be obtained by calling mallinfo.
-*/
-void  dlmalloc_stats(void);
-
-#endif /* ONLY_MSPACES */
-
-#if MSPACES
-
-/*
-  mspace is an opaque type representing an independent
-  region of space that supports mspace_malloc, etc.
-*/
-typedef void* mspace;
-
-/*
-  create_mspace creates and returns a new independent space with the
-  given initial capacity, or, if 0, the default granularity size.  It
-  returns null if there is no system memory available to create the
-  space.  If argument locked is non-zero, the space uses a separate
-  lock to control access. The capacity of the space will grow
-  dynamically as needed to service mspace_malloc requests.  You can
-  control the sizes of incremental increases of this space by
-  compiling with a different DEFAULT_GRANULARITY or dynamically
-  setting with mallopt(M_GRANULARITY, value).
-*/
-mspace create_mspace(size_t capacity, int locked);
-
-/*
-  destroy_mspace destroys the given space, and attempts to return all
-  of its memory back to the system, returning the total number of
-  bytes freed. After destruction, the results of access to all memory
-  used by the space become undefined.
-*/
-size_t destroy_mspace(mspace msp);
-
-/*
-  create_mspace_with_base uses the memory supplied as the initial base
-  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
-  space is used for bookkeeping, so the capacity must be at least this
-  large. (Otherwise 0 is returned.) When this initial space is
-  exhausted, additional memory will be obtained from the system.
-  Destroying this space will deallocate all additionally allocated
-  space (if possible) but not the initial base.
-*/
-mspace create_mspace_with_base(void* base, size_t capacity, int locked);
-
-/*
-  mspace_malloc behaves as malloc, but operates within
-  the given space.
-*/
-void* mspace_malloc(mspace msp, size_t bytes);
-
-/*
-  mspace_free behaves as free, but operates within
-  the given space.
-
-  If compiled with FOOTERS==1, mspace_free is not actually needed.
-  free may be called instead of mspace_free because freed chunks from
-  any space are handled by their originating spaces.
-*/
-void mspace_free(mspace msp, void* mem);
-
-/*
-  mspace_realloc behaves as realloc, but operates within
-  the given space.
-
-  If compiled with FOOTERS==1, mspace_realloc is not actually
-  needed.  realloc may be called instead of mspace_realloc because
-  realloced chunks from any space are handled by their originating
-  spaces.
-*/
-void* mspace_realloc(mspace msp, void* mem, size_t newsize);
-
-/*
-  mspace_calloc behaves as calloc, but operates within
-  the given space.
-*/
-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
-
-/*
-  mspace_memalign behaves as memalign, but operates within
-  the given space.
-*/
-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
-
-/*
-  mspace_independent_calloc behaves as independent_calloc, but
-  operates within the given space.
-*/
-void** mspace_independent_calloc(mspace msp, size_t n_elements,
-                                 size_t elem_size, void* chunks[]);
-
-/*
-  mspace_independent_comalloc behaves as independent_comalloc, but
-  operates within the given space.
-*/
-void** mspace_independent_comalloc(mspace msp, size_t n_elements,
-                                   size_t sizes[], void* chunks[]);
-
-/*
-  mspace_footprint() returns the number of bytes obtained from the
-  system for this space.
-*/
-size_t mspace_footprint(mspace msp);
-
-/*
-  mspace_max_footprint() returns the peak number of bytes obtained from the
-  system for this space.
-*/
-size_t mspace_max_footprint(mspace msp);
-
-
-#if !NO_MALLINFO
-/*
-  mspace_mallinfo behaves as mallinfo, but reports properties of
-  the given space.
-*/
-struct mallinfo mspace_mallinfo(mspace msp);
-#endif /* NO_MALLINFO */
-
-/*
-  mspace_malloc_stats behaves as malloc_stats, but reports
-  properties of the given space.
-*/
-void mspace_malloc_stats(mspace msp);
-
-/*
-  mspace_trim behaves as malloc_trim, but
-  operates within the given space.
-*/
-int mspace_trim(mspace msp, size_t pad);
-
-/*
-  An alias for mallopt.
-*/
-int mspace_mallopt(int, int);
-
-#endif /* MSPACES */
-
-#ifdef __cplusplus
-};  /* end of extern "C" */
-#endif /* __cplusplus */
-
-/*
-  ========================================================================
-  To make a fully customizable malloc.h header file, cut everything
-  above this line, put into file malloc.h, edit to suit, and #include it
-  on the next line, as well as in programs that use this malloc.
-  ========================================================================
-*/
-
-/* #include "malloc.h" */
-
-/*------------------------------ internal #includes ---------------------- */
-
-#ifdef WIN32
-#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
-#endif /* WIN32 */
-
-#include <stdio.h>       /* for printing in malloc_stats */
-
-#ifndef LACKS_ERRNO_H
-#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
-#endif /* LACKS_ERRNO_H */
-#if FOOTERS
-#include <time.h>        /* for magic initialization */
-#endif /* FOOTERS */
-#ifndef LACKS_STDLIB_H
-#include <stdlib.h>      /* for abort() */
-#endif /* LACKS_STDLIB_H */
-#ifdef DEBUG
-#if ABORT_ON_ASSERT_FAILURE
-#define assert(x) if(!(x)) ABORT
-#else /* ABORT_ON_ASSERT_FAILURE */
-#include <assert.h>
-#endif /* ABORT_ON_ASSERT_FAILURE */
-#else  /* DEBUG */
-#define assert(x)
-#endif /* DEBUG */
-#ifndef LACKS_STRING_H
-#include <string.h>      /* for memset etc */
-#endif  /* LACKS_STRING_H */
-#if USE_BUILTIN_FFS
-#ifndef LACKS_STRINGS_H
-#include <strings.h>     /* for ffs */
-#endif /* LACKS_STRINGS_H */
-#endif /* USE_BUILTIN_FFS */
-#if HAVE_MMAP
-#ifndef LACKS_SYS_MMAN_H
-#include <sys/mman.h>    /* for mmap */
-#endif /* LACKS_SYS_MMAN_H */
-#ifndef LACKS_FCNTL_H
-#include <fcntl.h>
-#endif /* LACKS_FCNTL_H */
-#endif /* HAVE_MMAP */
-#if HAVE_MORECORE
-#ifndef LACKS_UNISTD_H
-#include <unistd.h>     /* for sbrk */
-#else /* LACKS_UNISTD_H */
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
-extern void*     sbrk(ptrdiff_t);
-#endif /* FreeBSD etc */
-#endif /* LACKS_UNISTD_H */
-#endif /* HAVE_MMAP */
-
-#ifndef WIN32
-#ifndef malloc_getpagesize
-#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
-#    ifndef _SC_PAGE_SIZE
-#      define _SC_PAGE_SIZE _SC_PAGESIZE
-#    endif
-#  endif
-#  ifdef _SC_PAGE_SIZE
-#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
-#  else
-#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
-       extern size_t getpagesize();
-#      define malloc_getpagesize getpagesize()
-#    else
-#      ifdef WIN32 /* use supplied emulation of getpagesize */
-#        define malloc_getpagesize getpagesize()
-#      else
-#        ifndef LACKS_SYS_PARAM_H
-#          include <sys/param.h>
-#        endif
-#        ifdef EXEC_PAGESIZE
-#          define malloc_getpagesize EXEC_PAGESIZE
-#        else
-#          ifdef NBPG
-#            ifndef CLSIZE
-#              define malloc_getpagesize NBPG
-#            else
-#              define malloc_getpagesize (NBPG * CLSIZE)
-#            endif
-#          else
-#            ifdef NBPC
-#              define malloc_getpagesize NBPC
-#            else
-#              ifdef PAGESIZE
-#                define malloc_getpagesize PAGESIZE
-#              else /* just guess */
-#                define malloc_getpagesize ((size_t)4096U)
-#              endif
-#            endif
-#          endif
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-#endif
-
-/* ------------------- size_t and alignment properties -------------------- */
-
-/* The byte and bit size of a size_t */
-#define SIZE_T_SIZE         (sizeof(size_t))
-#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
-
-/* Some constants coerced to size_t */
-/* Annoying but necessary to avoid errors on some plaftorms */
-#define SIZE_T_ZERO         ((size_t)0)
-#define SIZE_T_ONE          ((size_t)1)
-#define SIZE_T_TWO          ((size_t)2)
-#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
-#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
-#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
-#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
-
-/* The bit mask value corresponding to MALLOC_ALIGNMENT */
-#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
-
-/* True if address a has acceptable alignment */
-#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
-
-/* the number of bytes to offset an address to align it */
-#define align_offset(A)\
- ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
-  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
-
-/* -------------------------- MMAP preliminaries ------------------------- */
-
-/*
-   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
-   checks to fail so compiler optimizer can delete code rather than
-   using so many "#if"s.
-*/
-
-
-/* MORECORE and MMAP must return MFAIL on failure */
-#define MFAIL                ((void*)(MAX_SIZE_T))
-#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
-
-#if !HAVE_MMAP
-#define IS_MMAPPED_BIT       (SIZE_T_ZERO)
-#define USE_MMAP_BIT         (SIZE_T_ZERO)
-#define CALL_MMAP(s)         MFAIL
-#define CALL_MUNMAP(a, s)    (-1)
-#define DIRECT_MMAP(s)       MFAIL
-
-#else /* HAVE_MMAP */
-#define IS_MMAPPED_BIT       (SIZE_T_ONE)
-#define USE_MMAP_BIT         (SIZE_T_ONE)
-
-#ifndef WIN32
-#define CALL_MUNMAP(a, s)    munmap((a), (s))
-#define MMAP_PROT            (PROT_READ|PROT_WRITE)
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
-#define MAP_ANONYMOUS        MAP_ANON
-#endif /* MAP_ANON */
-#ifdef MAP_ANONYMOUS
-#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
-#define CALL_MMAP(s)         mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
-#else /* MAP_ANONYMOUS */
-/*
-   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
-   is unlikely to be needed, but is supplied just in case.
-*/
-#define MMAP_FLAGS           (MAP_PRIVATE)
-static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
-#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \
-           (dev_zero_fd = open("/dev/zero", O_RDWR), \
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
-#endif /* MAP_ANONYMOUS */
-
-#define DIRECT_MMAP(s)       CALL_MMAP(s)
-#else /* WIN32 */
-
-/* Win32 MMAP via VirtualAlloc */
-static void* win32mmap(size_t size) {
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
-  return (ptr != 0)? ptr: MFAIL;
-}
-
-/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
-static void* win32direct_mmap(size_t size) {
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
-                           PAGE_READWRITE);
-  return (ptr != 0)? ptr: MFAIL;
-}
-
-/* This function supports releasing coalesed segments */
-static int win32munmap(void* ptr, size_t size) {
-  MEMORY_BASIC_INFORMATION minfo;
-  char* cptr = ptr;
-  while (size) {
-    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
-      return -1;
-    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
-        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
-      return -1;
-    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
-      return -1;
-    cptr += minfo.RegionSize;
-    size -= minfo.RegionSize;
-  }
-  return 0;
-}
-
-#define CALL_MMAP(s)         win32mmap(s)
-#define CALL_MUNMAP(a, s)    win32munmap((a), (s))
-#define DIRECT_MMAP(s)       win32direct_mmap(s)
-#endif /* WIN32 */
-#endif /* HAVE_MMAP */
-
-#if HAVE_MMAP && HAVE_MREMAP
-#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
-#else  /* HAVE_MMAP && HAVE_MREMAP */
-#define CALL_MREMAP(addr, osz, nsz, mv) MFAIL
-#endif /* HAVE_MMAP && HAVE_MREMAP */
-
-#if HAVE_MORECORE
-#define CALL_MORECORE(S)     MORECORE(S)
-#else  /* HAVE_MORECORE */
-#define CALL_MORECORE(S)     MFAIL
-#endif /* HAVE_MORECORE */
-
-/* mstate bit set if continguous morecore disabled or failed */
-#define USE_NONCONTIGUOUS_BIT (4U)
-
-/* segment bit set in create_mspace_with_base */
-#define EXTERN_BIT            (8U)
-
-
-/* --------------------------- Lock preliminaries ------------------------ */
-
-#if USE_LOCKS
-
-/*
-  When locks are defined, there are up to two global locks:
-
-  * If HAVE_MORECORE, morecore_mutex protects sequences of calls to
-    MORECORE.  In many cases sys_alloc requires two calls, that should
-    not be interleaved with calls by other threads.  This does not
-    protect against direct calls to MORECORE by other threads not
-    using this lock, so there is still code to cope the best we can on
-    interference.
-
-  * magic_init_mutex ensures that mparams.magic and other
-    unique mparams values are initialized only once.
-*/
-
-#ifndef WIN32
-/* By default use posix locks */
-#include <pthread.h>
-#define MLOCK_T pthread_mutex_t
-#define INITIAL_LOCK(l)      pthread_mutex_init(l, NULL)
-#define ACQUIRE_LOCK(l)      pthread_mutex_lock(l)
-#define RELEASE_LOCK(l)      pthread_mutex_unlock(l)
-
-#if HAVE_MORECORE
-static MLOCK_T morecore_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif /* HAVE_MORECORE */
-
-static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-#else /* WIN32 */
-/*
-   Because lock-protected regions have bounded times, and there
-   are no recursive lock calls, we can use simple spinlocks.
-*/
-
-#define MLOCK_T long
-static int win32_acquire_lock (MLOCK_T *sl) {
-  for (;;) {
-#ifdef InterlockedCompareExchangePointer
-    if (!InterlockedCompareExchange(sl, 1, 0))
-      return 0;
-#else  /* Use older void* version */
-    if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0))
-      return 0;
-#endif /* InterlockedCompareExchangePointer */
-    Sleep (0);
-  }
-}
-
-static void win32_release_lock (MLOCK_T *sl) {
-  InterlockedExchange (sl, 0);
-}
-
-#define INITIAL_LOCK(l)      *(l)=0
-#define ACQUIRE_LOCK(l)      win32_acquire_lock(l)
-#define RELEASE_LOCK(l)      win32_release_lock(l)
-#if HAVE_MORECORE
-static MLOCK_T morecore_mutex;
-#endif /* HAVE_MORECORE */
-static MLOCK_T magic_init_mutex;
-#endif /* WIN32 */
-
-#define USE_LOCK_BIT               (2U)
-#else  /* USE_LOCKS */
-#define USE_LOCK_BIT               (0U)
-#define INITIAL_LOCK(l)
-#endif /* USE_LOCKS */
-
-#if USE_LOCKS && HAVE_MORECORE
-#define ACQUIRE_MORECORE_LOCK()    ACQUIRE_LOCK(&morecore_mutex);
-#define RELEASE_MORECORE_LOCK()    RELEASE_LOCK(&morecore_mutex);
-#else /* USE_LOCKS && HAVE_MORECORE */
-#define ACQUIRE_MORECORE_LOCK()
-#define RELEASE_MORECORE_LOCK()
-#endif /* USE_LOCKS && HAVE_MORECORE */
-
-#if USE_LOCKS
-#define ACQUIRE_MAGIC_INIT_LOCK()  ACQUIRE_LOCK(&magic_init_mutex);
-#define RELEASE_MAGIC_INIT_LOCK()  RELEASE_LOCK(&magic_init_mutex);
-#else  /* USE_LOCKS */
-#define ACQUIRE_MAGIC_INIT_LOCK()
-#define RELEASE_MAGIC_INIT_LOCK()
-#endif /* USE_LOCKS */
-
-
-/* -----------------------  Chunk representations ------------------------ */
-
-/*
-  (The following includes lightly edited explanations by Colin Plumb.)
-
-  The malloc_chunk declaration below is misleading (but accurate and
-  necessary).  It declares a "view" into memory allowing access to
-  necessary fields at known offsets from a given base.
-
-  Chunks of memory are maintained using a `boundary tag' method as
-  originally described by Knuth.  (See the paper by Paul Wilson
-  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
-  techniques.)  Sizes of free chunks are stored both in the front of
-  each chunk and at the end.  This makes consolidating fragmented
-  chunks into bigger chunks fast.  The head fields also hold bits
-  representing whether chunks are free or in use.
-
-  Here are some pictures to make it clearer.  They are "exploded" to
-  show that the state of a chunk can be thought of as extending from
-  the high 31 bits of the head field of its header through the
-  prev_foot and PINUSE_BIT bit of the following chunk header.
-
-  A chunk that's in use looks like:
-
-   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | Size of previous chunk (if P = 1)                             |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
-         | Size of this chunk                                         1| +-+
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               |
-         +-                                                             -+
-         |                                                               |
-         +-                                                             -+
-         |                                                               :
-         +-      size - sizeof(size_t) available payload bytes          -+
-         :                                                               |
- chunk-> +-                                                             -+
-         |                                                               |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
-       | Size of next chunk (may or may not be in use)               | +-+
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-    And if it's free, it looks like this:
-
-   chunk-> +-                                                             -+
-           | User payload (must be in use, or we would have merged!)       |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
-         | Size of this chunk                                         0| +-+
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Next pointer                                                  |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Prev pointer                                                  |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               :
-         +-      size - sizeof(struct chunk) unused bytes               -+
-         :                                                               |
- chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Size of this chunk                                            |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
-       | Size of next chunk (must be in use, or we would have merged)| +-+
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               :
-       +- User payload                                                -+
-       :                                                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-                                                                     |0|
-                                                                     +-+
-  Note that since we always merge adjacent free chunks, the chunks
-  adjacent to a free chunk must be in use.
-
-  Given a pointer to a chunk (which can be derived trivially from the
-  payload pointer) we can, in O(1) time, find out whether the adjacent
-  chunks are free, and if so, unlink them from the lists that they
-  are on and merge them with the current chunk.
-
-  Chunks always begin on even word boundaries, so the mem portion
-  (which is returned to the user) is also on an even word boundary, and
-  thus at least double-word aligned.
-
-  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
-  chunk size (which is always a multiple of two words), is an in-use
-  bit for the *previous* chunk.  If that bit is *clear*, then the
-  word before the current chunk size contains the previous chunk
-  size, and can be used to find the front of the previous chunk.
-  The very first chunk allocated always has this bit set, preventing
-  access to non-existent (or non-owned) memory. If pinuse is set for
-  any given chunk, then you CANNOT determine the size of the
-  previous chunk, and might even get a memory addressing fault when
-  trying to do so.
-
-  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
-  the chunk size redundantly records whether the current chunk is
-  inuse. This redundancy enables usage checks within free and realloc,
-  and reduces indirection when freeing and consolidating chunks.
-
-  Each freshly allocated chunk must have both cinuse and pinuse set.
-  That is, each allocated chunk borders either a previously allocated
-  and still in-use chunk, or the base of its memory arena. This is
-  ensured by making all allocations from the the `lowest' part of any
-  found chunk.  Further, no free chunk physically borders another one,
-  so each free chunk is known to be preceded and followed by either
-  inuse chunks or the ends of memory.
-
-  Note that the `foot' of the current chunk is actually represented
-  as the prev_foot of the NEXT chunk. This makes it easier to
-  deal with alignments etc but can be very confusing when trying
-  to extend or adapt this code.
-
-  The exceptions to all this are
-
-     1. The special chunk `top' is the top-most available chunk (i.e.,
-        the one bordering the end of available memory). It is treated
-        specially.  Top is never included in any bin, is used only if
-        no other chunk is available, and is released back to the
-        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
-        the top chunk is treated as larger (and thus less well
-        fitting) than any other available chunk.  The top chunk
-        doesn't update its trailing size field since there is no next
-        contiguous chunk that would have to index off it. However,
-        space is still allocated for it (TOP_FOOT_SIZE) to enable
-        separation or merging when space is extended.
-
-     3. Chunks allocated via mmap, which have the lowest-order bit
-        (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set
-        PINUSE_BIT in their head fields.  Because they are allocated
-        one-by-one, each must carry its own prev_foot field, which is
-        also used to hold the offset this chunk has within its mmapped
-        region, which is needed to preserve alignment. Each mmapped
-        chunk is trailed by the first two fields of a fake next-chunk
-        for sake of usage checks.
-
-*/
-
-struct malloc_chunk {
-  size_t               prev_foot;  /* Size of previous chunk (if free).  */
-  size_t               head;       /* Size and inuse bits. */
-  struct malloc_chunk* fd;         /* double links -- used only if free. */
-  struct malloc_chunk* bk;
-};
-
-typedef struct malloc_chunk  mchunk;
-typedef struct malloc_chunk* mchunkptr;
-typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
-typedef unsigned int bindex_t;         /* Described below */
-typedef unsigned int binmap_t;         /* Described below */
-typedef unsigned int flag_t;           /* The type of various bit flag sets */
-
-/* ------------------- Chunks sizes and alignments ----------------------- */
-
-#define MCHUNK_SIZE         (sizeof(mchunk))
-
-#if FOOTERS
-#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
-#else /* FOOTERS */
-#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
-#endif /* FOOTERS */
-
-/* MMapped chunks need a second word of overhead ... */
-#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
-/* ... and additional padding for fake next-chunk at foot */
-#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
-
-/* The smallest size we can malloc is an aligned minimal chunk */
-#define MIN_CHUNK_SIZE\
-  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
-
-/* conversion from malloc headers to user pointers, and back */
-#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
-#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
-/* chunk associated with aligned address A */
-#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
-
-/* Bounds on request (not chunk) sizes. */
-#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
-#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
-
-/* pad request bytes into a usable size */
-#define pad_request(req) \
-   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
-
-/* pad request, checking for minimum (but not maximum) */
-#define request2size(req) \
-  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
-
-
-/* ------------------ Operations on head and foot fields ----------------- */
-
-/*
-  The head field of a chunk is or'ed with PINUSE_BIT when previous
-  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
-  use. If the chunk was obtained with mmap, the prev_foot field has
-  IS_MMAPPED_BIT set, otherwise holding the offset of the base of the
-  mmapped region to the base of the chunk.
-*/
-
-#define PINUSE_BIT          (SIZE_T_ONE)
-#define CINUSE_BIT          (SIZE_T_TWO)
-#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
-
-/* Head value for fenceposts */
-#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
-
-/* extraction of fields from head words */
-#define cinuse(p)           ((p)->head & CINUSE_BIT)
-#define pinuse(p)           ((p)->head & PINUSE_BIT)
-#define chunksize(p)        ((p)->head & ~(INUSE_BITS))
-
-#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
-#define clear_cinuse(p)     ((p)->head &= ~CINUSE_BIT)
-
-/* Treat space at ptr +/- offset as a chunk */
-#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
-#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
-
-/* Ptr to next or previous physical malloc_chunk. */
-#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~INUSE_BITS)))
-#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
-
-/* extract next chunk's pinuse bit */
-#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
-
-/* Get/set size at footer */
-#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
-#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
-
-/* Set size, pinuse bit, and foot */
-#define set_size_and_pinuse_of_free_chunk(p, s)\
-  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
-
-/* Set size, pinuse bit, foot, and clear next pinuse */
-#define set_free_with_pinuse(p, s, n)\
-  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
-
-#define is_mmapped(p)\
-  (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT))
-
-/* Get the internal overhead associated with chunk p */
-#define overhead_for(p)\
- (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
-
-/* Return true if malloced space is not necessarily cleared */
-#if MMAP_CLEARS
-#define calloc_must_clear(p) (!is_mmapped(p))
-#else /* MMAP_CLEARS */
-#define calloc_must_clear(p) (1)
-#endif /* MMAP_CLEARS */
-
-/* ---------------------- Overlaid data structures ----------------------- */
-
-/*
-  When chunks are not in use, they are treated as nodes of either
-  lists or trees.
-
-  "Small"  chunks are stored in circular doubly-linked lists, and look
-  like this:
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Size of previous chunk                            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `head:' |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Forward pointer to next chunk in list             |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Back pointer to previous chunk in list            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Unused space (may be 0 bytes long)                .
-            .                                                               .
-            .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `foot:' |             Size of chunk, in bytes                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-  Larger chunks are kept in a form of bitwise digital trees (aka
-  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
-  free chunks greater than 256 bytes, their size doesn't impose any
-  constraints on user chunk sizes.  Each node looks like:
-
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Size of previous chunk                            |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `head:' |             Size of chunk, in bytes                         |P|
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Forward pointer to next chunk of same size        |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Back pointer to previous chunk of same size       |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to left child (child[0])                  |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to right child (child[1])                 |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Pointer to parent                                 |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             bin index of this chunk                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-            |             Unused space                                      .
-            .                                                               |
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    `foot:' |             Size of chunk, in bytes                           |
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
-  of the same size are arranged in a circularly-linked list, with only
-  the oldest chunk (the next to be used, in our FIFO ordering)
-  actually in the tree.  (Tree members are distinguished by a non-null
-  parent pointer.)  If a chunk with the same size an an existing node
-  is inserted, it is linked off the existing node using pointers that
-  work in the same way as fd/bk pointers of small chunks.
-
-  Each tree contains a power of 2 sized range of chunk sizes (the
-  smallest is 0x100 <= x < 0x180), which is is divided in half at each
-  tree level, with the chunks in the smaller half of the range (0x100
-  <= x < 0x140 for the top nose) in the left subtree and the larger
-  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
-  done by inspecting individual bits.
-
-  Using these rules, each node's left subtree contains all smaller
-  sizes than its right subtree.  However, the node at the root of each
-  subtree has no particular ordering relationship to either.  (The
-  dividing line between the subtree sizes is based on trie relation.)
-  If we remove the last chunk of a given size from the interior of the
-  tree, we need to replace it with a leaf node.  The tree ordering
-  rules permit a node to be replaced by any leaf below it.
-
-  The smallest chunk in a tree (a common operation in a best-fit
-  allocator) can be found by walking a path to the leftmost leaf in
-  the tree.  Unlike a usual binary tree, where we follow left child
-  pointers until we reach a null, here we follow the right child
-  pointer any time the left one is null, until we reach a leaf with
-  both child pointers null. The smallest chunk in the tree will be
-  somewhere along that path.
-
-  The worst case number of steps to add, find, or remove a node is
-  bounded by the number of bits differentiating chunks within
-  bins. Under current bin calculations, this ranges from 6 up to 21
-  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
-  is of course much better.
-*/
-
-struct malloc_tree_chunk {
-  /* The first four fields must be compatible with malloc_chunk */
-  size_t                    prev_foot;
-  size_t                    head;
-  struct malloc_tree_chunk* fd;
-  struct malloc_tree_chunk* bk;
-
-  struct malloc_tree_chunk* child[2];
-  struct malloc_tree_chunk* parent;
-  bindex_t                  index;
-};
-
-typedef struct malloc_tree_chunk  tchunk;
-typedef struct malloc_tree_chunk* tchunkptr;
-typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
-
-/* A little helper macro for trees */
-#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
-
-/* ----------------------------- Segments -------------------------------- */
-
-/*
-  Each malloc space may include non-contiguous segments, held in a
-  list headed by an embedded malloc_segment record representing the
-  top-most space. Segments also include flags holding properties of
-  the space. Large chunks that are directly allocated by mmap are not
-  included in this list. They are instead independently created and
-  destroyed without otherwise keeping track of them.
-
-  Segment management mainly comes into play for spaces allocated by
-  MMAP.  Any call to MMAP might or might not return memory that is
-  adjacent to an existing segment.  MORECORE normally contiguously
-  extends the current space, so this space is almost always adjacent,
-  which is simpler and faster to deal with. (This is why MORECORE is
-  used preferentially to MMAP when both are available -- see
-  sys_alloc.)  When allocating using MMAP, we don't use any of the
-  hinting mechanisms (inconsistently) supported in various
-  implementations of unix mmap, or distinguish reserving from
-  committing memory. Instead, we just ask for space, and exploit
-  contiguity when we get it.  It is probably possible to do
-  better than this on some systems, but no general scheme seems
-  to be significantly better.
-
-  Management entails a simpler variant of the consolidation scheme
-  used for chunks to reduce fragmentation -- new adjacent memory is
-  normally prepended or appended to an existing segment. However,
-  there are limitations compared to chunk consolidation that mostly
-  reflect the fact that segment processing is relatively infrequent
-  (occurring only when getting memory from system) and that we
-  don't expect to have huge numbers of segments:
-
-  * Segments are not indexed, so traversal requires linear scans.  (It
-    would be possible to index these, but is not worth the extra
-    overhead and complexity for most programs on most platforms.)
-  * New segments are only appended to old ones when holding top-most
-    memory; if they cannot be prepended to others, they are held in
-    different segments.
-
-  Except for the top-most segment of an mstate, each segment record
-  is kept at the tail of its segment. Segments are added by pushing
-  segment records onto the list headed by &mstate.seg for the
-  containing mstate.
-
-  Segment flags control allocation/merge/deallocation policies:
-  * If EXTERN_BIT set, then we did not allocate this segment,
-    and so should not try to deallocate or merge with others.
-    (This currently holds only for the initial segment passed
-    into create_mspace_with_base.)
-  * If IS_MMAPPED_BIT set, the segment may be merged with
-    other surrounding mmapped segments and trimmed/de-allocated
-    using munmap.
-  * If neither bit is set, then the segment was obtained using
-    MORECORE so can be merged with surrounding MORECORE'd segments
-    and deallocated/trimmed using MORECORE with negative arguments.
-*/
-
-struct malloc_segment {
-  char*        base;             /* base address */
-  size_t       size;             /* allocated size */
-  struct malloc_segment* next;   /* ptr to next segment */
-  flag_t       sflags;           /* mmap and extern flag */
-};
-
-#define is_mmapped_segment(S)  ((S)->sflags & IS_MMAPPED_BIT)
-#define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)
-
-typedef struct malloc_segment  msegment;
-typedef struct malloc_segment* msegmentptr;
-
-/* ---------------------------- malloc_state ----------------------------- */
-
-/*
-   A malloc_state holds all of the bookkeeping for a space.
-   The main fields are:
-
-  Top
-    The topmost chunk of the currently active segment. Its size is
-    cached in topsize.  The actual size of topmost space is
-    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
-    fenceposts and segment records if necessary when getting more
-    space from the system.  The size at which to autotrim top is
-    cached from mparams in trim_check, except that it is disabled if
-    an autotrim fails.
-
-  Designated victim (dv)
-    This is the preferred chunk for servicing small requests that
-    don't have exact fits.  It is normally the chunk split off most
-    recently to service another small request.  Its size is cached in
-    dvsize. The link fields of this chunk are not maintained since it
-    is not kept in a bin.
-
-  SmallBins
-    An array of bin headers for free chunks.  These bins hold chunks
-    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
-    chunks of all the same size, spaced 8 bytes apart.  To simplify
-    use in double-linked lists, each bin header acts as a malloc_chunk
-    pointing to the real first node, if it exists (else pointing to
-    itself).  This avoids special-casing for headers.  But to avoid
-    waste, we allocate only the fd/bk pointers of bins, and then use
-    repositioning tricks to treat these as the fields of a chunk.
-
-  TreeBins
-    Treebins are pointers to the roots of trees holding a range of
-    sizes. There are 2 equally spaced treebins for each power of two
-    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
-    larger.
-
-  Bin maps
-    There is one bit map for small bins ("smallmap") and one for
-    treebins ("treemap).  Each bin sets its bit when non-empty, and
-    clears the bit when empty.  Bit operations are then used to avoid
-    bin-by-bin searching -- nearly all "search" is done without ever
-    looking at bins that won't be selected.  The bit maps
-    conservatively use 32 bits per map word, even if on 64bit system.
-    For a good description of some of the bit-based techniques used
-    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
-    supplement at http://hackersdelight.org/). Many of these are
-    intended to reduce the branchiness of paths through malloc etc, as
-    well as to reduce the number of memory locations read or written.
-
-  Segments
-    A list of segments headed by an embedded malloc_segment record
-    representing the initial space.
-
-  Address check support
-    The least_addr field is the least address ever obtained from
-    MORECORE or MMAP. Attempted frees and reallocs of any address less
-    than this are trapped (unless INSECURE is defined).
-
-  Magic tag
-    A cross-check field that should always hold same value as mparams.magic.
-
-  Flags
-    Bits recording whether to use MMAP, locks, or contiguous MORECORE
-
-  Statistics
-    Each space keeps track of current and maximum system memory
-    obtained via MORECORE or MMAP.
-
-  Locking
-    If USE_LOCKS is defined, the "mutex" lock is acquired and released
-    around every public call using this mspace.
-*/
-
-/* Bin types, widths and sizes */
-#define NSMALLBINS        (32U)
-#define NTREEBINS         (32U)
-#define SMALLBIN_SHIFT    (3U)
-#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
-#define TREEBIN_SHIFT     (8U)
-#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
-#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
-#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
-
-struct malloc_state {
-  binmap_t   smallmap;
-  binmap_t   treemap;
-  size_t     dvsize;
-  size_t     topsize;
-  char*      least_addr;
-  mchunkptr  dv;
-  mchunkptr  top;
-  size_t     trim_check;
-  size_t     magic;
-  mchunkptr  smallbins[(NSMALLBINS+1)*2];
-  tbinptr    treebins[NTREEBINS];
-  size_t     footprint;
-  size_t     max_footprint;
-  flag_t     mflags;
-#if USE_LOCKS
-  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
-#endif /* USE_LOCKS */
-  msegment   seg;
-};
-
-typedef struct malloc_state*    mstate;
-
-/* ------------- Global malloc_state and malloc_params ------------------- */
-
-/*
-  malloc_params holds global properties, including those that can be
-  dynamically set using mallopt. There is a single instance, mparams,
-  initialized in init_mparams.
-*/
-
-struct malloc_params {
-  size_t magic;
-  size_t page_size;
-  size_t granularity;
-  size_t mmap_threshold;
-  size_t trim_threshold;
-  flag_t default_mflags;
-};
-
-static struct malloc_params mparams;
-
-/* The global malloc_state used for all non-"mspace" calls */
-static struct malloc_state _gm_;
-#define gm                 (&_gm_)
-#define is_global(M)       ((M) == &_gm_)
-#define is_initialized(M)  ((M)->top != 0)
-
-/* -------------------------- system alloc setup ------------------------- */
-
-/* Operations on mflags */
-
-#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
-#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
-#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
-
-#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
-#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
-#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
-
-#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
-#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
-
-#define set_lock(M,L)\
- ((M)->mflags = (L)?\
-  ((M)->mflags | USE_LOCK_BIT) :\
-  ((M)->mflags & ~USE_LOCK_BIT))
-
-/* page-align a size */
-#define page_align(S)\
- (((S) + (mparams.page_size)) & ~(mparams.page_size - SIZE_T_ONE))
-
-/* granularity-align a size */
-#define granularity_align(S)\
-  (((S) + (mparams.granularity)) & ~(mparams.granularity - SIZE_T_ONE))
-
-#define is_page_aligned(S)\
-   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
-#define is_granularity_aligned(S)\
-   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
-
-/*  True if segment S holds address A */
-#define segment_holds(S, A)\
-  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
-
-/* Return segment holding given address */
-static msegmentptr segment_holding(mstate m, char* addr) {
-  msegmentptr sp = &m->seg;
-  for (;;) {
-    if (addr >= sp->base && addr < sp->base + sp->size)
-      return sp;
-    if ((sp = sp->next) == 0)
-      return 0;
-  }
-}
-
-/* Return true if segment contains a segment link */
-static int has_segment_link(mstate m, msegmentptr ss) {
-  msegmentptr sp = &m->seg;
-  for (;;) {
-    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
-      return 1;
-    if ((sp = sp->next) == 0)
-      return 0;
-  }
-}
-
-#ifndef MORECORE_CANNOT_TRIM
-#define should_trim(M,s)  ((s) > (M)->trim_check)
-#else  /* MORECORE_CANNOT_TRIM */
-#define should_trim(M,s)  (0)
-#endif /* MORECORE_CANNOT_TRIM */
-
-/*
-  TOP_FOOT_SIZE is padding at the end of a segment, including space
-  that may be needed to place segment records and fenceposts when new
-  noncontiguous segments are added.
-*/
-#define TOP_FOOT_SIZE\
-  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
-
-
-/* -------------------------------  Hooks -------------------------------- */
-
-/*
-  PREACTION should be defined to return 0 on success, and nonzero on
-  failure. If you are not using locking, you can redefine these to do
-  anything you like.
-*/
-
-#if USE_LOCKS
-
-/* Ensure locks are initialized */
-#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams())
-
-#define PREACTION(M)  ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
-#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
-#else /* USE_LOCKS */
-
-#ifndef PREACTION
-#define PREACTION(M) (0)
-#endif  /* PREACTION */
-
-#ifndef POSTACTION
-#define POSTACTION(M)
-#endif  /* POSTACTION */
-
-#endif /* USE_LOCKS */
-
-/*
-  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
-  USAGE_ERROR_ACTION is triggered on detected bad frees and
-  reallocs. The argument p is an address that might have triggered the
-  fault. It is ignored by the two predefined actions, but might be
-  useful in custom actions that try to help diagnose errors.
-*/
-
-#if PROCEED_ON_ERROR
-
-/* A count of the number of corruption errors causing resets */
-int malloc_corruption_error_count;
-
-/* default corruption action */
-static void reset_on_error(mstate m);
-
-#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
-#define USAGE_ERROR_ACTION(m, p)
-
-#else /* PROCEED_ON_ERROR */
-
-#ifndef CORRUPTION_ERROR_ACTION
-#define CORRUPTION_ERROR_ACTION(m) ABORT
-#endif /* CORRUPTION_ERROR_ACTION */
-
-#ifndef USAGE_ERROR_ACTION
-#define USAGE_ERROR_ACTION(m,p) ABORT
-#endif /* USAGE_ERROR_ACTION */
-
-#endif /* PROCEED_ON_ERROR */
-
-/* -------------------------- Debugging setup ---------------------------- */
-
-#if ! DEBUG
-
-#define check_free_chunk(M,P)
-#define check_inuse_chunk(M,P)
-#define check_malloced_chunk(M,P,N)
-#define check_mmapped_chunk(M,P)
-#define check_malloc_state(M)
-#define check_top_chunk(M,P)
-
-#else /* DEBUG */
-#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
-#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
-#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
-#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
-#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
-#define check_malloc_state(M)       do_check_malloc_state(M)
-
-static void   do_check_any_chunk(mstate m, mchunkptr p);
-static void   do_check_top_chunk(mstate m, mchunkptr p);
-static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
-static void   do_check_inuse_chunk(mstate m, mchunkptr p);
-static void   do_check_free_chunk(mstate m, mchunkptr p);
-static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
-static void   do_check_tree(mstate m, tchunkptr t);
-static void   do_check_treebin(mstate m, bindex_t i);
-static void   do_check_smallbin(mstate m, bindex_t i);
-static void   do_check_malloc_state(mstate m);
-static int    bin_find(mstate m, mchunkptr x);
-static size_t traverse_and_check(mstate m);
-#endif /* DEBUG */
-
-/* ---------------------------- Indexing Bins ---------------------------- */
-
-#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
-#define small_index(s)      ((s)  >> SMALLBIN_SHIFT)
-#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
-#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
-
-/* addressing by index. See above about smallbin repositioning */
-#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
-#define treebin_at(M,i)     (&((M)->treebins[i]))
-
-/* assign tree index for size S to variable I */
-#if defined(__GNUC__) && defined(i386) && defined(ASSEMBLY_VERSION)
-#define compute_tree_index(S, I)\
-{\
-  size_t X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int K;\
-    __asm__("bsrl %1,%0\n\t" : "=r" (K) : "rm"  (X));\
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
-  }\
-}
-#else /* GNUC */
-#define compute_tree_index(S, I)\
-{\
-  size_t X = S >> TREEBIN_SHIFT;\
-  if (X == 0)\
-    I = 0;\
-  else if (X > 0xFFFF)\
-    I = NTREEBINS-1;\
-  else {\
-    unsigned int Y = (unsigned int)X;\
-    unsigned int N = ((Y - 0x100) >> 16) & 8;\
-    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
-    N += K;\
-    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
-    K = 14 - N + ((Y <<= K) >> 15);\
-    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
-  }\
-}
-#endif /* GNUC */
-
-/* Bit representing maximum resolved size in a treebin at i */
-#define bit_for_tree_index(i) \
-   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
-
-/* Shift placing maximum resolved bit in a treebin at i as sign bit */
-#define leftshift_for_tree_index(i) \
-   ((i == NTREEBINS-1)? 0 : \
-    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
-
-/* The size of the smallest chunk held in bin with index i */
-#define minsize_for_tree_index(i) \
-   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
-   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
-
-
-/* ------------------------ Operations on bin maps ----------------------- */
-
-/* bit corresponding to given index */
-#define idx2bit(i)              ((binmap_t)(1) << (i))
-
-/* Mark/Clear bits with given index */
-#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
-#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
-#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
-
-#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
-#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
-#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
-
-/* index corresponding to given bit */
-
-#if defined(__GNUC__) && defined(i386) && defined(ASSEMBLY_VERSION)
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int J;\
-  __asm__("bsfl %1,%0\n\t" : "=r" (J) : "rm" (X));\
-  I = (bindex_t)J;\
-}
-
-#else /* GNUC */
-#if  USE_BUILTIN_FFS
-#define compute_bit2idx(X, I) I = ffs(X)-1
-
-#else /* USE_BUILTIN_FFS */
-#define compute_bit2idx(X, I)\
-{\
-  unsigned int Y = X - 1;\
-  unsigned int K = Y >> (16-4) & 16;\
-  unsigned int N = K;        Y >>= K;\
-  N += K = Y >> (8-3) &  8;  Y >>= K;\
-  N += K = Y >> (4-2) &  4;  Y >>= K;\
-  N += K = Y >> (2-1) &  2;  Y >>= K;\
-  N += K = Y >> (1-0) &  1;  Y >>= K;\
-  I = (bindex_t)(N + Y);\
-}
-#endif /* USE_BUILTIN_FFS */
-#endif /* GNUC */
-
-/* isolate the least set bit of a bitmap */
-#define least_bit(x)         ((x) & -(x))
-
-/* mask with all bits to left of least bit of x on */
-#define left_bits(x)         ((x<<1) | -(x<<1))
-
-/* mask with all bits to left of or equal to least bit of x on */
-#define same_or_left_bits(x) ((x) | -(x))
-
-
-/* ----------------------- Runtime Check Support ------------------------- */
-
-/*
-  For security, the main invariant is that malloc/free/etc never
-  writes to a static address other than malloc_state, unless static
-  malloc_state itself has been corrupted, which cannot occur via
-  malloc (because of these checks). In essence this means that we
-  believe all pointers, sizes, maps etc held in malloc_state, but
-  check all of those linked or offsetted from other embedded data
-  structures.  These checks are interspersed with main code in a way
-  that tends to minimize their run-time cost.
-
-  When FOOTERS is defined, in addition to range checking, we also
-  verify footer fields of inuse chunks, which can be used guarantee
-  that the mstate controlling malloc/free is intact.  This is a
-  streamlined version of the approach described by William Robertson
-  et al in "Run-time Detection of Heap-based Overflows" LISA'03
-  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
-  of an inuse chunk holds the xor of its mstate and a random seed,
-  that is checked upon calls to free() and realloc().  This is
-  (probablistically) unguessable from outside the program, but can be
-  computed by any code successfully malloc'ing any chunk, so does not
-  itself provide protection against code that has already broken
-  security through some other means.  Unlike Robertson et al, we
-  always dynamically check addresses of all offset chunks (previous,
-  next, etc). This turns out to be cheaper than relying on hashes.
-*/
-
-#if !INSECURE
-/* Check if address a is at least as high as any from MORECORE or MMAP */
-#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
-/* Check if address of next chunk n is higher than base chunk p */
-#define ok_next(p, n)    ((char*)(p) < (char*)(n))
-/* Check if p has its cinuse bit on */
-#define ok_cinuse(p)     cinuse(p)
-/* Check if p has its pinuse bit on */
-#define ok_pinuse(p)     pinuse(p)
-
-#else /* !INSECURE */
-#define ok_address(M, a) (1)
-#define ok_next(b, n)    (1)
-#define ok_cinuse(p)     (1)
-#define ok_pinuse(p)     (1)
-#endif /* !INSECURE */
-
-#if (FOOTERS && !INSECURE)
-/* Check if (alleged) mstate m has expected magic field */
-#define ok_magic(M)      ((M)->magic == mparams.magic)
-#else  /* (FOOTERS && !INSECURE) */
-#define ok_magic(M)      (1)
-#endif /* (FOOTERS && !INSECURE) */
-
-
-/* In gcc, use __builtin_expect to minimize impact of checks */
-#if !INSECURE
-#if defined(__GNUC__) && __GNUC__ >= 3
-#define RTCHECK(e)  __builtin_expect(e, 1)
-#else /* GNUC */
-#define RTCHECK(e)  (e)
-#endif /* GNUC */
-#else /* !INSECURE */
-#define RTCHECK(e)  (1)
-#endif /* !INSECURE */
-
-/* macros to set up inuse chunks with or without footers */
-
-#if !FOOTERS
-
-#define mark_inuse_foot(M,p,s)
-
-/* Set cinuse bit and pinuse bit of next chunk */
-#define set_inuse(M,p,s)\
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
-
-/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
-#define set_inuse_and_pinuse(M,p,s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
-
-/* Set size, cinuse and pinuse bit of this chunk */
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
-
-#else /* FOOTERS */
-
-/* Set foot of inuse chunk to be xor of mstate and seed */
-#define mark_inuse_foot(M,p,s)\
-  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
-
-#define get_mstate_for(p)\
-  ((mstate)(((mchunkptr)((char*)(p) +\
-    (chunksize(p))))->prev_foot ^ mparams.magic))
-
-#define set_inuse(M,p,s)\
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
-  mark_inuse_foot(M,p,s))
-
-#define set_inuse_and_pinuse(M,p,s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
- mark_inuse_foot(M,p,s))
-
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
-  mark_inuse_foot(M, p, s))
-
-#endif /* !FOOTERS */
-
-/* ---------------------------- setting mparams -------------------------- */
-
-/* Initialize mparams */
-static int init_mparams(void) {
-  if (mparams.page_size == 0) {
-    size_t s;
-
-    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
-    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
-#if MORECORE_CONTIGUOUS
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
-#else  /* MORECORE_CONTIGUOUS */
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
-#endif /* MORECORE_CONTIGUOUS */
-
-#if (FOOTERS && !INSECURE)
-    {
-#if USE_DEV_RANDOM
-      int fd;
-      unsigned char buf[sizeof(size_t)];
-      /* Try to use /dev/urandom, else fall back on using time */
-      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
-          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
-        s = *((size_t *) buf);
-        close(fd);
-      }
-      else
-#endif /* USE_DEV_RANDOM */
-        s = (size_t)(time(0) ^ (size_t)0x55555555U);
-
-      s |= (size_t)8U;    /* ensure nonzero */
-      s &= ~(size_t)7U;   /* improve chances of fault for bad values */
-
-    }
-#else /* (FOOTERS && !INSECURE) */
-    s = (size_t)0x58585858U;
-#endif /* (FOOTERS && !INSECURE) */
-    ACQUIRE_MAGIC_INIT_LOCK();
-    if (mparams.magic == 0) {
-      mparams.magic = s;
-      /* Set up lock for main malloc area */
-      INITIAL_LOCK(&gm->mutex);
-      gm->mflags = mparams.default_mflags;
-    }
-    RELEASE_MAGIC_INIT_LOCK();
-
-#ifndef WIN32
-    mparams.page_size = malloc_getpagesize;
-    mparams.granularity = ((DEFAULT_GRANULARITY != 0)?
-                           DEFAULT_GRANULARITY : mparams.page_size);
-#else /* WIN32 */
-    {
-      SYSTEM_INFO system_info;
-      GetSystemInfo(&system_info);
-      mparams.page_size = system_info.dwPageSize;
-      mparams.granularity = system_info.dwAllocationGranularity;
-    }
-#endif /* WIN32 */
-
-    /* Sanity-check configuration:
-       size_t must be unsigned and as wide as pointer type.
-       ints must be at least 4 bytes.
-       alignment must be at least 8.
-       Alignment, min chunk size, and page size must all be powers of 2.
-    */
-    if ((sizeof(size_t) != sizeof(char*)) ||
-        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
-        (sizeof(int) < 4)  ||
-        (MALLOC_ALIGNMENT < (size_t)8U) ||
-        ((MALLOC_ALIGNMENT    & (MALLOC_ALIGNMENT-SIZE_T_ONE))    != 0) ||
-        ((MCHUNK_SIZE         & (MCHUNK_SIZE-SIZE_T_ONE))         != 0) ||
-        ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) ||
-        ((mparams.page_size   & (mparams.page_size-SIZE_T_ONE))   != 0))
-      ABORT;
-  }
-  return 0;
-}
-
-/* support for mallopt */
-static int change_mparam(int param_number, int value) {
-  size_t val = (size_t)value;
-  init_mparams();
-  switch(param_number) {
-  case M_TRIM_THRESHOLD:
-    mparams.trim_threshold = val;
-    return 1;
-  case M_GRANULARITY:
-    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
-      mparams.granularity = val;
-      return 1;
-    }
-    else
-      return 0;
-  case M_MMAP_THRESHOLD:
-    mparams.mmap_threshold = val;
-    return 1;
-  default:
-    return 0;
-  }
-}
-
-#if DEBUG
-/* ------------------------- Debugging Support --------------------------- */
-
-/* Check properties of any chunk, whether free, inuse, mmapped etc  */
-static void do_check_any_chunk(mstate m, mchunkptr p) {
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-}
-
-/* Check properties of top chunk */
-static void do_check_top_chunk(mstate m, mchunkptr p) {
-  msegmentptr sp = segment_holding(m, (char*)p);
-  size_t  sz = chunksize(p);
-  assert(sp != 0);
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-  assert(sz == m->topsize);
-  assert(sz > 0);
-  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
-  assert(pinuse(p));
-  assert(!next_pinuse(p));
-}
-
-/* Check properties of (inuse) mmapped chunks */
-static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
-  size_t  sz = chunksize(p);
-  size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD);
-  assert(is_mmapped(p));
-  assert(use_mmap(m));
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
-  assert(ok_address(m, p));
-  assert(!is_small(sz));
-  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
-  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
-  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
-}
-
-/* Check properties of inuse chunks */
-static void do_check_inuse_chunk(mstate m, mchunkptr p) {
-  do_check_any_chunk(m, p);
-  assert(cinuse(p));
-  assert(next_pinuse(p));
-  /* If not pinuse and not mmapped, previous chunk has OK offset */
-  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
-  if (is_mmapped(p))
-    do_check_mmapped_chunk(m, p);
-}
-
-/* Check properties of free chunks */
-static void do_check_free_chunk(mstate m, mchunkptr p) {
-  size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
-  mchunkptr next = chunk_plus_offset(p, sz);
-  do_check_any_chunk(m, p);
-  assert(!cinuse(p));
-  assert(!next_pinuse(p));
-  assert (!is_mmapped(p));
-  if (p != m->dv && p != m->top) {
-    if (sz >= MIN_CHUNK_SIZE) {
-      assert((sz & CHUNK_ALIGN_MASK) == 0);
-      assert(is_aligned(chunk2mem(p)));
-      assert(next->prev_foot == sz);
-      assert(pinuse(p));
-      assert (next == m->top || cinuse(next));
-      assert(p->fd->bk == p);
-      assert(p->bk->fd == p);
-    }
-    else  /* markers are always of size SIZE_T_SIZE */
-      assert(sz == SIZE_T_SIZE);
-  }
-}
-
-/* Check properties of malloced chunks at the point they are malloced */
-static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
-  if (mem != 0) {
-    mchunkptr p = mem2chunk(mem);
-    size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT);
-    do_check_inuse_chunk(m, p);
-    assert((sz & CHUNK_ALIGN_MASK) == 0);
-    assert(sz >= MIN_CHUNK_SIZE);
-    assert(sz >= s);
-    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
-    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
-  }
-}
-
-/* Check a tree and its subtrees.  */
-static void do_check_tree(mstate m, tchunkptr t) {
-  tchunkptr head = 0;
-  tchunkptr u = t;
-  bindex_t tindex = t->index;
-  size_t tsize = chunksize(t);
-  bindex_t idx;
-  compute_tree_index(tsize, idx);
-  assert(tindex == idx);
-  assert(tsize >= MIN_LARGE_SIZE);
-  assert(tsize >= minsize_for_tree_index(idx));
-  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
-
-  do { /* traverse through chain of same-sized nodes */
-    do_check_any_chunk(m, ((mchunkptr)u));
-    assert(u->index == tindex);
-    assert(chunksize(u) == tsize);
-    assert(!cinuse(u));
-    assert(!next_pinuse(u));
-    assert(u->fd->bk == u);
-    assert(u->bk->fd == u);
-    if (u->parent == 0) {
-      assert(u->child[0] == 0);
-      assert(u->child[1] == 0);
-    }
-    else {
-      assert(head == 0); /* only one node on chain has parent */
-      head = u;
-      assert(u->parent != u);
-      assert (u->parent->child[0] == u ||
-              u->parent->child[1] == u ||
-              *((tbinptr*)(u->parent)) == u);
-      if (u->child[0] != 0) {
-        assert(u->child[0]->parent == u);
-        assert(u->child[0] != u);
-        do_check_tree(m, u->child[0]);
-      }
-      if (u->child[1] != 0) {
-        assert(u->child[1]->parent == u);
-        assert(u->child[1] != u);
-        do_check_tree(m, u->child[1]);
-      }
-      if (u->child[0] != 0 && u->child[1] != 0) {
-        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
-      }
-    }
-    u = u->fd;
-  } while (u != t);
-  assert(head != 0);
-}
-
-/*  Check all the chunks in a treebin.  */
-static void do_check_treebin(mstate m, bindex_t i) {
-  tbinptr* tb = treebin_at(m, i);
-  tchunkptr t = *tb;
-  int empty = (m->treemap & (1U << i)) == 0;
-  if (t == 0)
-    assert(empty);
-  if (!empty)
-    do_check_tree(m, t);
-}
-
-/*  Check all the chunks in a smallbin.  */
-static void do_check_smallbin(mstate m, bindex_t i) {
-  sbinptr b = smallbin_at(m, i);
-  mchunkptr p = b->bk;
-  unsigned int empty = (m->smallmap & (1U << i)) == 0;
-  if (p == b)
-    assert(empty);
-  if (!empty) {
-    for (; p != b; p = p->bk) {
-      size_t size = chunksize(p);
-      mchunkptr q;
-      /* each chunk claims to be free */
-      do_check_free_chunk(m, p);
-      /* chunk belongs in bin */
-      assert(small_index(size) == i);
-      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
-      /* chunk is followed by an inuse chunk */
-      q = next_chunk(p);
-      if (q->head != FENCEPOST_HEAD)
-        do_check_inuse_chunk(m, q);
-    }
-  }
-}
-
-/* Find x in a bin. Used in other check functions. */
-static int bin_find(mstate m, mchunkptr x) {
-  size_t size = chunksize(x);
-  if (is_small(size)) {
-    bindex_t sidx = small_index(size);
-    sbinptr b = smallbin_at(m, sidx);
-    if (smallmap_is_marked(m, sidx)) {
-      mchunkptr p = b;
-      do {
-        if (p == x)
-          return 1;
-      } while ((p = p->fd) != b);
-    }
-  }
-  else {
-    bindex_t tidx;
-    compute_tree_index(size, tidx);
-    if (treemap_is_marked(m, tidx)) {
-      tchunkptr t = *treebin_at(m, tidx);
-      size_t sizebits = size << leftshift_for_tree_index(tidx);
-      while (t != 0 && chunksize(t) != size) {
-        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
-        sizebits <<= 1;
-      }
-      if (t != 0) {
-        tchunkptr u = t;
-        do {
-          if (u == (tchunkptr)x)
-            return 1;
-        } while ((u = u->fd) != t);
-      }
-    }
-  }
-  return 0;
-}
-
-/* Traverse each chunk and check it; return total */
-static size_t traverse_and_check(mstate m) {
-  size_t sum = 0;
-  if (is_initialized(m)) {
-    msegmentptr s = &m->seg;
-    sum += m->topsize + TOP_FOOT_SIZE;
-    while (s != 0) {
-      mchunkptr q = align_as_chunk(s->base);
-      mchunkptr lastq = 0;
-      assert(pinuse(q));
-      while (segment_holds(s, q) &&
-             q != m->top && q->head != FENCEPOST_HEAD) {
-        sum += chunksize(q);
-        if (cinuse(q)) {
-          assert(!bin_find(m, q));
-          do_check_inuse_chunk(m, q);
-        }
-        else {
-          assert(q == m->dv || bin_find(m, q));
-          assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */
-          do_check_free_chunk(m, q);
-        }
-        lastq = q;
-        q = next_chunk(q);
-      }
-      s = s->next;
-    }
-  }
-  return sum;
-}
-
-/* Check all properties of malloc_state. */
-static void do_check_malloc_state(mstate m) {
-  bindex_t i;
-  size_t total;
-  /* check bins */
-  for (i = 0; i < NSMALLBINS; ++i)
-    do_check_smallbin(m, i);
-  for (i = 0; i < NTREEBINS; ++i)
-    do_check_treebin(m, i);
-
-  if (m->dvsize != 0) { /* check dv chunk */
-    do_check_any_chunk(m, m->dv);
-    assert(m->dvsize == chunksize(m->dv));
-    assert(m->dvsize >= MIN_CHUNK_SIZE);
-    assert(bin_find(m, m->dv) == 0);
-  }
-
-  if (m->top != 0) {   /* check top chunk */
-    do_check_top_chunk(m, m->top);
-    assert(m->topsize == chunksize(m->top));
-    assert(m->topsize > 0);
-    assert(bin_find(m, m->top) == 0);
-  }
-
-  total = traverse_and_check(m);
-  assert(total <= m->footprint);
-  assert(m->footprint <= m->max_footprint);
-}
-#endif /* DEBUG */
-
-/* ----------------------------- statistics ------------------------------ */
-
-#if !NO_MALLINFO
-static struct mallinfo internal_mallinfo(mstate m) {
-  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-  if (!PREACTION(m)) {
-    check_malloc_state(m);
-    if (is_initialized(m)) {
-      size_t nfree = SIZE_T_ONE; /* top always free */
-      size_t mfree = m->topsize + TOP_FOOT_SIZE;
-      size_t sum = mfree;
-      msegmentptr s = &m->seg;
-      while (s != 0) {
-        mchunkptr q = align_as_chunk(s->base);
-        while (segment_holds(s, q) &&
-               q != m->top && q->head != FENCEPOST_HEAD) {
-          size_t sz = chunksize(q);
-          sum += sz;
-          if (!cinuse(q)) {
-            mfree += sz;
-            ++nfree;
-          }
-          q = next_chunk(q);
-        }
-        s = s->next;
-      }
-
-      nm.arena    = sum;
-      nm.ordblks  = nfree;
-      nm.hblkhd   = m->footprint - sum;
-      nm.usmblks  = m->max_footprint;
-      nm.uordblks = m->footprint - mfree;
-      nm.fordblks = mfree;
-      nm.keepcost = m->topsize;
-    }
-
-    POSTACTION(m);
-  }
-  return nm;
-}
-#endif /* !NO_MALLINFO */
-
-static void internal_malloc_stats(mstate m) {
-  if (!PREACTION(m)) {
-    size_t maxfp = 0;
-    size_t fp = 0;
-    size_t used = 0;
-    check_malloc_state(m);
-    if (is_initialized(m)) {
-      msegmentptr s = &m->seg;
-      maxfp = m->max_footprint;
-      fp = m->footprint;
-      used = fp - (m->topsize + TOP_FOOT_SIZE);
-
-      while (s != 0) {
-        mchunkptr q = align_as_chunk(s->base);
-        while (segment_holds(s, q) &&
-               q != m->top && q->head != FENCEPOST_HEAD) {
-          if (!cinuse(q))
-            used -= chunksize(q);
-          q = next_chunk(q);
-        }
-        s = s->next;
-      }
-    }
-
-    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
-    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
-    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
-
-    POSTACTION(m);
-  }
-}
-
-/* ----------------------- Operations on smallbins ----------------------- */
-
-/*
-  Various forms of linking and unlinking are defined as macros.  Even
-  the ones for trees, which are very long but have very short typical
-  paths.  This is ugly but reduces reliance on inlining support of
-  compilers.
-*/
-
-/* Link a free chunk into a smallbin  */
-#define insert_small_chunk(M, P, S) {\
-  bindex_t I  = small_index(S);\
-  mchunkptr B = smallbin_at(M, I);\
-  mchunkptr F = B;\
-  assert(S >= MIN_CHUNK_SIZE);\
-  if (!smallmap_is_marked(M, I))\
-    mark_smallmap(M, I);\
-  else if (RTCHECK(ok_address(M, B->fd)))\
-    F = B->fd;\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-  B->fd = P;\
-  F->bk = P;\
-  P->fd = F;\
-  P->bk = B;\
-}
-
-/* Unlink a chunk from a smallbin  */
-#define unlink_small_chunk(M, P, S) {\
-  mchunkptr F = P->fd;\
-  mchunkptr B = P->bk;\
-  bindex_t I = small_index(S);\
-  assert(P != B);\
-  assert(P != F);\
-  assert(chunksize(P) == small_index2size(I));\
-  if (F == B)\
-    clear_smallmap(M, I);\
-  else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\
-                   (B == smallbin_at(M,I) || ok_address(M, B)))) {\
-    F->bk = B;\
-    B->fd = F;\
-  }\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-}
-
-/* Unlink the first chunk from a smallbin */
-#define unlink_first_small_chunk(M, B, P, I) {\
-  mchunkptr F = P->fd;\
-  assert(P != B);\
-  assert(P != F);\
-  assert(chunksize(P) == small_index2size(I));\
-  if (B == F)\
-    clear_smallmap(M, I);\
-  else if (RTCHECK(ok_address(M, F))) {\
-    B->fd = F;\
-    F->bk = B;\
-  }\
-  else {\
-    CORRUPTION_ERROR_ACTION(M);\
-  }\
-}
-
-/* Replace dv node, binning the old one */
-/* Used only when dvsize known to be small */
-#define replace_dv(M, P, S) {\
-  size_t DVS = M->dvsize;\
-  if (DVS != 0) {\
-    mchunkptr DV = M->dv;\
-    assert(is_small(DVS));\
-    insert_small_chunk(M, DV, DVS);\
-  }\
-  M->dvsize = S;\
-  M->dv = P;\
-}
-
-/* ------------------------- Operations on trees ------------------------- */
-
-/* Insert chunk into tree */
-#define insert_large_chunk(M, X, S) {\
-  tbinptr* H;\
-  bindex_t I;\
-  compute_tree_index(S, I);\
-  H = treebin_at(M, I);\
-  X->index = I;\
-  X->child[0] = X->child[1] = 0;\
-  if (!treemap_is_marked(M, I)) {\
-    mark_treemap(M, I);\
-    *H = X;\
-    X->parent = (tchunkptr)H;\
-    X->fd = X->bk = X;\
-  }\
-  else {\
-    tchunkptr T = *H;\
-    size_t K = S << leftshift_for_tree_index(I);\
-    for (;;) {\
-      if (chunksize(T) != S) {\
-        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
-        K <<= 1;\
-        if (*C != 0)\
-          T = *C;\
-        else if (RTCHECK(ok_address(M, C))) {\
-          *C = X;\
-          X->parent = T;\
-          X->fd = X->bk = X;\
-          break;\
-        }\
-        else {\
-          CORRUPTION_ERROR_ACTION(M);\
-          break;\
-        }\
-      }\
-      else {\
-        tchunkptr F = T->fd;\
-        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
-          T->fd = F->bk = X;\
-          X->fd = F;\
-          X->bk = T;\
-          X->parent = 0;\
-          break;\
-        }\
-        else {\
-          CORRUPTION_ERROR_ACTION(M);\
-          break;\
-        }\
-      }\
-    }\
-  }\
-}
-
-/*
-  Unlink steps:
-
-  1. If x is a chained node, unlink it from its same-sized fd/bk links
-     and choose its bk node as its replacement.
-  2. If x was the last node of its size, but not a leaf node, it must
-     be replaced with a leaf node (not merely one with an open left or
-     right), to make sure that lefts and rights of descendents
-     correspond properly to bit masks.  We use the rightmost descendent
-     of x.  We could use any other leaf, but this is easy to locate and
-     tends to counteract removal of leftmosts elsewhere, and so keeps
-     paths shorter than minimally guaranteed.  This doesn't loop much
-     because on average a node in a tree is near the bottom.
-  3. If x is the base of a chain (i.e., has parent links) relink
-     x's parent and children to x's replacement (or null if none).
-*/
-
-#define unlink_large_chunk(M, X) {\
-  tchunkptr XP = X->parent;\
-  tchunkptr R;\
-  if (X->bk != X) {\
-    tchunkptr F = X->fd;\
-    R = X->bk;\
-    if (RTCHECK(ok_address(M, F))) {\
-      F->bk = R;\
-      R->fd = F;\
-    }\
-    else {\
-      CORRUPTION_ERROR_ACTION(M);\
-    }\
-  }\
-  else {\
-    tchunkptr* RP;\
-    if (((R = *(RP = &(X->child[1]))) != 0) ||\
-        ((R = *(RP = &(X->child[0]))) != 0)) {\
-      tchunkptr* CP;\
-      while ((*(CP = &(R->child[1])) != 0) ||\
-             (*(CP = &(R->child[0])) != 0)) {\
-        R = *(RP = CP);\
-      }\
-      if (RTCHECK(ok_address(M, RP)))\
-        *RP = 0;\
-      else {\
-        CORRUPTION_ERROR_ACTION(M);\
-      }\
-    }\
-  }\
-  if (XP != 0) {\
-    tbinptr* H = treebin_at(M, X->index);\
-    if (X == *H) {\
-      if ((*H = R) == 0) \
-        clear_treemap(M, X->index);\
-    }\
-    else if (RTCHECK(ok_address(M, XP))) {\
-      if (XP->child[0] == X) \
-        XP->child[0] = R;\
-      else \
-        XP->child[1] = R;\
-    }\
-    else\
-      CORRUPTION_ERROR_ACTION(M);\
-    if (R != 0) {\
-      if (RTCHECK(ok_address(M, R))) {\
-        tchunkptr C0, C1;\
-        R->parent = XP;\
-        if ((C0 = X->child[0]) != 0) {\
-          if (RTCHECK(ok_address(M, C0))) {\
-            R->child[0] = C0;\
-            C0->parent = R;\
-          }\
-          else\
-            CORRUPTION_ERROR_ACTION(M);\
-        }\
-        if ((C1 = X->child[1]) != 0) {\
-          if (RTCHECK(ok_address(M, C1))) {\
-            R->child[1] = C1;\
-            C1->parent = R;\
-          }\
-          else\
-            CORRUPTION_ERROR_ACTION(M);\
-        }\
-      }\
-      else\
-        CORRUPTION_ERROR_ACTION(M);\
-    }\
-  }\
-}
-
-/* Relays to large vs small bin operations */
-
-#define insert_chunk(M, P, S)\
-  if (is_small(S)) insert_small_chunk(M, P, S)\
-  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
-
-#define unlink_chunk(M, P, S)\
-  if (is_small(S)) unlink_small_chunk(M, P, S)\
-  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
-
-
-/* Relays to internal calls to malloc/free from realloc, memalign etc */
-
-#if ONLY_MSPACES
-#define internal_malloc(m, b) mspace_malloc(m, b)
-#define internal_free(m, mem) mspace_free(m,mem);
-#else /* ONLY_MSPACES */
-#if MSPACES
-#define internal_malloc(m, b)\
-   (m == gm)? dlmalloc(b) : mspace_malloc(m, b)
-#define internal_free(m, mem)\
-   if (m == gm) dlfree(mem); else mspace_free(m,mem);
-#else /* MSPACES */
-#define internal_malloc(m, b) dlmalloc(b)
-#define internal_free(m, mem) dlfree(mem)
-#endif /* MSPACES */
-#endif /* ONLY_MSPACES */
-
-/* -----------------------  Direct-mmapping chunks ----------------------- */
-
-/*
-  Directly mmapped chunks are set up with an offset to the start of
-  the mmapped region stored in the prev_foot field of the chunk. This
-  allows reconstruction of the required argument to MUNMAP when freed,
-  and also allows adjustment of the returned chunk to meet alignment
-  requirements (especially in memalign).  There is also enough space
-  allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain
-  the PINUSE bit so frees can be checked.
-*/
-
-/* Malloc using mmap */
-static void* mmap_alloc(mstate m, size_t nb) {
-  size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
-  if (mmsize > nb) {     /* Check for wrap around 0 */
-    char* mm = (char*)(DIRECT_MMAP(mmsize));
-    if (mm != CMFAIL) {
-      size_t offset = align_offset(chunk2mem(mm));
-      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
-      mchunkptr p = (mchunkptr)(mm + offset);
-      p->prev_foot = offset | IS_MMAPPED_BIT;
-      (p)->head = (psize|CINUSE_BIT);
-      mark_inuse_foot(m, p, psize);
-      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
-      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
-
-      if (mm < m->least_addr)
-        m->least_addr = mm;
-      if ((m->footprint += mmsize) > m->max_footprint)
-        m->max_footprint = m->footprint;
-      assert(is_aligned(chunk2mem(p)));
-      check_mmapped_chunk(m, p);
-      return chunk2mem(p);
-    }
-  }
-  return 0;
-}
-
-/* Realloc using mmap */
-static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) {
-  size_t oldsize = chunksize(oldp);
-  if (is_small(nb)) /* Can't shrink mmap regions below small size */
-    return 0;
-  /* Keep old chunk if big enough but not too big */
-  if (oldsize >= nb + SIZE_T_SIZE &&
-      (oldsize - nb) <= (mparams.granularity << 1))
-    return oldp;
-  else {
-    size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT;
-    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
-    size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES +
-                                         CHUNK_ALIGN_MASK);
-    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
-                                  oldmmsize, newmmsize, 1);
-    if (cp != CMFAIL) {
-      mchunkptr newp = (mchunkptr)(cp + offset);
-      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
-      newp->head = (psize|CINUSE_BIT);
-      mark_inuse_foot(m, newp, psize);
-      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
-      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
-
-      if (cp < m->least_addr)
-        m->least_addr = cp;
-      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
-        m->max_footprint = m->footprint;
-      check_mmapped_chunk(m, newp);
-      return newp;
-    }
-  }
-  return 0;
-}
-
-/* -------------------------- mspace management -------------------------- */
-
-/* Initialize top chunk and its size */
-static void init_top(mstate m, mchunkptr p, size_t psize) {
-  /* Ensure alignment */
-  size_t offset = align_offset(chunk2mem(p));
-  p = (mchunkptr)((char*)p + offset);
-  psize -= offset;
-
-  m->top = p;
-  m->topsize = psize;
-  p->head = psize | PINUSE_BIT;
-  /* set size of fake trailing chunk holding overhead space only once */
-  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
-  m->trim_check = mparams.trim_threshold; /* reset on each update */
-}
-
-/* Initialize bins for a new mstate that is otherwise zeroed out */
-static void init_bins(mstate m) {
-  /* Establish circular links for smallbins */
-  bindex_t i;
-  for (i = 0; i < NSMALLBINS; ++i) {
-    sbinptr bin = smallbin_at(m,i);
-    bin->fd = bin->bk = bin;
-  }
-}
-
-#if PROCEED_ON_ERROR
-
-/* default corruption action */
-static void reset_on_error(mstate m) {
-  int i;
-  ++malloc_corruption_error_count;
-  /* Reinitialize fields to forget about all memory */
-  m->smallbins = m->treebins = 0;
-  m->dvsize = m->topsize = 0;
-  m->seg.base = 0;
-  m->seg.size = 0;
-  m->seg.next = 0;
-  m->top = m->dv = 0;
-  for (i = 0; i < NTREEBINS; ++i)
-    *treebin_at(m, i) = 0;
-  init_bins(m);
-}
-#endif /* PROCEED_ON_ERROR */
-
-/* Allocate chunk and prepend remainder with chunk in successor base. */
-static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
-                           size_t nb) {
-  mchunkptr p = align_as_chunk(newbase);
-  mchunkptr oldfirst = align_as_chunk(oldbase);
-  size_t psize = (char*)oldfirst - (char*)p;
-  mchunkptr q = chunk_plus_offset(p, nb);
-  size_t qsize = psize - nb;
-  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
-
-  assert((char*)oldfirst > (char*)q);
-  assert(pinuse(oldfirst));
-  assert(qsize >= MIN_CHUNK_SIZE);
-
-  /* consolidate remainder with first chunk of old base */
-  if (oldfirst == m->top) {
-    size_t tsize = m->topsize += qsize;
-    m->top = q;
-    q->head = tsize | PINUSE_BIT;
-    check_top_chunk(m, q);
-  }
-  else if (oldfirst == m->dv) {
-    size_t dsize = m->dvsize += qsize;
-    m->dv = q;
-    set_size_and_pinuse_of_free_chunk(q, dsize);
-  }
-  else {
-    if (!cinuse(oldfirst)) {
-      size_t nsize = chunksize(oldfirst);
-      unlink_chunk(m, oldfirst, nsize);
-      oldfirst = chunk_plus_offset(oldfirst, nsize);
-      qsize += nsize;
-    }
-    set_free_with_pinuse(q, qsize, oldfirst);
-    insert_chunk(m, q, qsize);
-    check_free_chunk(m, q);
-  }
-
-  check_malloced_chunk(m, chunk2mem(p), nb);
-  return chunk2mem(p);
-}
-
-
-/* Add a segment to hold a new noncontiguous region */
-static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
-  /* Determine locations and sizes of segment, fenceposts, old top */
-  char* old_top = (char*)m->top;
-  msegmentptr oldsp = segment_holding(m, old_top);
-  char* old_end = oldsp->base + oldsp->size;
-  size_t ssize = pad_request(sizeof(struct malloc_segment));
-  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
-  size_t offset = align_offset(chunk2mem(rawsp));
-  char* asp = rawsp + offset;
-  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
-  mchunkptr sp = (mchunkptr)csp;
-  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
-  mchunkptr tnext = chunk_plus_offset(sp, ssize);
-  mchunkptr p = tnext;
-  int nfences = 0;
-
-  /* reset top to new space */
-  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
-
-  /* Set up segment record */
-  assert(is_aligned(ss));
-  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
-  *ss = m->seg; /* Push current record */
-  m->seg.base = tbase;
-  m->seg.size = tsize;
-  m->seg.sflags = mmapped;
-  m->seg.next = ss;
-
-  /* Insert trailing fenceposts */
-  for (;;) {
-    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
-    p->head = FENCEPOST_HEAD;
-    ++nfences;
-    if ((char*)(&(nextp->head)) < old_end)
-      p = nextp;
-    else
-      break;
-  }
-  assert(nfences >= 2);
-
-  /* Insert the rest of old top into a bin as an ordinary free chunk */
-  if (csp != old_top) {
-    mchunkptr q = (mchunkptr)old_top;
-    size_t psize = csp - old_top;
-    mchunkptr tn = chunk_plus_offset(q, psize);
-    set_free_with_pinuse(q, psize, tn);
-    insert_chunk(m, q, psize);
-  }
-
-  check_top_chunk(m, m->top);
-}
-
-/* -------------------------- System allocation -------------------------- */
-
-/* Get memory from system using MORECORE or MMAP */
-static void* sys_alloc(mstate m, size_t nb) {
-  char* tbase = CMFAIL;
-  size_t tsize = 0;
-  flag_t mmap_flag = 0;
-
-  init_mparams();
-
-  /* Directly map large chunks */
-  if (use_mmap(m) && nb >= mparams.mmap_threshold) {
-    void* mem = mmap_alloc(m, nb);
-    if (mem != 0)
-      return mem;
-  }
-
-  /*
-    Try getting memory in any of three ways (in most-preferred to
-    least-preferred order):
-    1. A call to MORECORE that can normally contiguously extend memory.
-       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
-       or main space is mmapped or a previous contiguous call failed)
-    2. A call to MMAP new space (disabled if not HAVE_MMAP).
-       Note that under the default settings, if MORECORE is unable to
-       fulfill a request, and HAVE_MMAP is true, then mmap is
-       used as a noncontiguous system allocator. This is a useful backup
-       strategy for systems with holes in address spaces -- in this case
-       sbrk cannot contiguously expand the heap, but mmap may be able to
-       find space.
-    3. A call to MORECORE that cannot usually contiguously extend memory.
-       (disabled if not HAVE_MORECORE)
-  */
-
-  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
-    char* br = CMFAIL;
-    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
-    size_t asize = 0;
-    ACQUIRE_MORECORE_LOCK();
-
-    if (ss == 0) {  /* First time through or recovery */
-      char* base = (char*)CALL_MORECORE(0);
-      if (base != CMFAIL) {
-        asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
-        /* Adjust to end on a page boundary */
-        if (!is_page_aligned(base))
-          asize += (page_align((size_t)base) - (size_t)base);
-        /* Can't call MORECORE if size is negative when treated as signed */
-        if (asize < HALF_MAX_SIZE_T &&
-            (br = (char*)(CALL_MORECORE(asize))) == base) {
-          tbase = base;
-          tsize = asize;
-        }
-      }
-    }
-    else {
-      /* Subtract out existing available top space from MORECORE request. */
-      asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE);
-      /* Use mem here only if it did continuously extend old space */
-      if (asize < HALF_MAX_SIZE_T &&
-          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {
-        tbase = br;
-        tsize = asize;
-      }
-    }
-
-    if (tbase == CMFAIL) {    /* Cope with partial failure */
-      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
-        if (asize < HALF_MAX_SIZE_T &&
-            asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) {
-          size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize);
-          if (esize < HALF_MAX_SIZE_T) {
-            char* end = (char*)CALL_MORECORE(esize);
-            if (end != CMFAIL)
-              asize += esize;
-            else {            /* Can't use; try to release */
-              CALL_MORECORE(-asize);
-              br = CMFAIL;
-            }
-          }
-        }
-      }
-      if (br != CMFAIL) {    /* Use the space we did get */
-        tbase = br;
-        tsize = asize;
-      }
-      else
-        disable_contiguous(m); /* Don't try contiguous path in the future */
-    }
-
-    RELEASE_MORECORE_LOCK();
-  }
-
-  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
-    size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE;
-    size_t rsize = granularity_align(req);
-    if (rsize > nb) { /* Fail if wraps around zero */
-      char* mp = (char*)(CALL_MMAP(rsize));
-      if (mp != CMFAIL) {
-        tbase = mp;
-        tsize = rsize;
-        mmap_flag = IS_MMAPPED_BIT;
-      }
-    }
-  }
-
-  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
-    size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE);
-    if (asize < HALF_MAX_SIZE_T) {
-      char* br = CMFAIL;
-      char* end = CMFAIL;
-      ACQUIRE_MORECORE_LOCK();
-      br = (char*)(CALL_MORECORE(asize));
-      end = (char*)(CALL_MORECORE(0));
-      RELEASE_MORECORE_LOCK();
-      if (br != CMFAIL && end != CMFAIL && br < end) {
-        size_t ssize = end - br;
-        if (ssize > nb + TOP_FOOT_SIZE) {
-          tbase = br;
-          tsize = ssize;
-        }
-      }
-    }
-  }
-
-  if (tbase != CMFAIL) {
-
-    if ((m->footprint += tsize) > m->max_footprint)
-      m->max_footprint = m->footprint;
-
-    if (!is_initialized(m)) { /* first-time initialization */
-      m->seg.base = m->least_addr = tbase;
-      m->seg.size = tsize;
-      m->seg.sflags = mmap_flag;
-      m->magic = mparams.magic;
-      init_bins(m);
-      if (is_global(m))
-        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
-      else {
-        /* Offset top by embedded malloc_state */
-        mchunkptr mn = next_chunk(mem2chunk(m));
-        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
-      }
-    }
-
-    else {
-      /* Try to merge with an existing segment */
-      msegmentptr sp = &m->seg;
-      while (sp != 0 && tbase != sp->base + sp->size)
-        sp = sp->next;
-      if (sp != 0 &&
-          !is_extern_segment(sp) &&
-          (sp->sflags & IS_MMAPPED_BIT) == mmap_flag &&
-          segment_holds(sp, m->top)) { /* append */
-        sp->size += tsize;
-        init_top(m, m->top, m->topsize + tsize);
-      }
-      else {
-        if (tbase < m->least_addr)
-          m->least_addr = tbase;
-        sp = &m->seg;
-        while (sp != 0 && sp->base != tbase + tsize)
-          sp = sp->next;
-        if (sp != 0 &&
-            !is_extern_segment(sp) &&
-            (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) {
-          char* oldbase = sp->base;
-          sp->base = tbase;
-          sp->size += tsize;
-          return prepend_alloc(m, tbase, oldbase, nb);
-        }
-        else
-          add_segment(m, tbase, tsize, mmap_flag);
-      }
-    }
-
-    if (nb < m->topsize) { /* Allocate from new or extended top space */
-      size_t rsize = m->topsize -= nb;
-      mchunkptr p = m->top;
-      mchunkptr r = m->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
-      check_top_chunk(m, m->top);
-      check_malloced_chunk(m, chunk2mem(p), nb);
-      return chunk2mem(p);
-    }
-  }
-
-  MALLOC_FAILURE_ACTION;
-  return 0;
-}
-
-/* -----------------------  system deallocation -------------------------- */
-
-/* Unmap and unlink any mmapped segments that don't contain used chunks */
-static size_t release_unused_segments(mstate m) {
-  size_t released = 0;
-  msegmentptr pred = &m->seg;
-  msegmentptr sp = pred->next;
-  while (sp != 0) {
-    char* base = sp->base;
-    size_t size = sp->size;
-    msegmentptr next = sp->next;
-    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
-      mchunkptr p = align_as_chunk(base);
-      size_t psize = chunksize(p);
-      /* Can unmap if first chunk holds entire segment and not pinned */
-      if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
-        tchunkptr tp = (tchunkptr)p;
-        assert(segment_holds(sp, (char*)sp));
-        if (p == m->dv) {
-          m->dv = 0;
-          m->dvsize = 0;
-        }
-        else {
-          unlink_large_chunk(m, tp);
-        }
-        if (CALL_MUNMAP(base, size) == 0) {
-          released += size;
-          m->footprint -= size;
-          /* unlink obsoleted record */
-          sp = pred;
-          sp->next = next;
-        }
-        else { /* back out if cannot unmap */
-          insert_large_chunk(m, tp, psize);
-        }
-      }
-    }
-    pred = sp;
-    sp = next;
-  }
-  return released;
-}
-
-static int sys_trim(mstate m, size_t pad) {
-  size_t released = 0;
-  if (pad < MAX_REQUEST && is_initialized(m)) {
-    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
-
-    if (m->topsize > pad) {
-      /* Shrink top space in granularity-size units, keeping at least one */
-      size_t unit = mparams.granularity;
-      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
-                      SIZE_T_ONE) * unit;
-      msegmentptr sp = segment_holding(m, (char*)m->top);
-
-      if (!is_extern_segment(sp)) {
-        if (is_mmapped_segment(sp)) {
-          if (HAVE_MMAP &&
-              sp->size >= extra &&
-              !has_segment_link(m, sp)) { /* can't shrink if pinned */
-            size_t newsize = sp->size - extra;
-            /* Prefer mremap, fall back to munmap */
-            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
-                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
-              released = extra;
-            }
-          }
-        }
-        else if (HAVE_MORECORE) {
-          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
-            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
-          ACQUIRE_MORECORE_LOCK();
-          {
-            /* Make sure end of memory is where we last set it. */
-            char* old_br = (char*)(CALL_MORECORE(0));
-            if (old_br == sp->base + sp->size) {
-              char* rel_br = (char*)(CALL_MORECORE(-extra));
-              char* new_br = (char*)(CALL_MORECORE(0));
-              if (rel_br != CMFAIL && new_br < old_br)
-                released = old_br - new_br;
-            }
-          }
-          RELEASE_MORECORE_LOCK();
-        }
-      }
-
-      if (released != 0) {
-        sp->size -= released;
-        m->footprint -= released;
-        init_top(m, m->top, m->topsize - released);
-        check_top_chunk(m, m->top);
-      }
-    }
-
-    /* Unmap any unused mmapped segments */
-    if (HAVE_MMAP)
-      released += release_unused_segments(m);
-
-    /* On failure, disable autotrim to avoid repeated failed future calls */
-    if (released == 0)
-      m->trim_check = MAX_SIZE_T;
-  }
-
-  return (released != 0)? 1 : 0;
-}
-
-/* ---------------------------- malloc support --------------------------- */
-
-/* allocate a large request from the best fitting chunk in a treebin */
-static void* tmalloc_large(mstate m, size_t nb) {
-  tchunkptr v = 0;
-  size_t rsize = -nb; /* Unsigned negation */
-  tchunkptr t;
-  bindex_t idx;
-  compute_tree_index(nb, idx);
-
-  if ((t = *treebin_at(m, idx)) != 0) {
-    /* Traverse tree for this bin looking for node with size == nb */
-    size_t sizebits = nb << leftshift_for_tree_index(idx);
-    tchunkptr rst = 0;  /* The deepest untaken right subtree */
-    for (;;) {
-      tchunkptr rt;
-      size_t trem = chunksize(t) - nb;
-      if (trem < rsize) {
-        v = t;
-        if ((rsize = trem) == 0)
-          break;
-      }
-      rt = t->child[1];
-      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
-      if (rt != 0 && rt != t)
-        rst = rt;
-      if (t == 0) {
-        t = rst; /* set t to least subtree holding sizes > nb */
-        break;
-      }
-      sizebits <<= 1;
-    }
-  }
-
-  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
-    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
-    if (leftbits != 0) {
-      bindex_t i;
-      binmap_t leastbit = least_bit(leftbits);
-      compute_bit2idx(leastbit, i);
-      t = *treebin_at(m, i);
-    }
-  }
-
-  while (t != 0) { /* find smallest of tree or subtree */
-    size_t trem = chunksize(t) - nb;
-    if (trem < rsize) {
-      rsize = trem;
-      v = t;
-    }
-    t = leftmost_child(t);
-  }
-
-  /*  If dv is a better fit, return 0 so malloc will use it */
-  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
-    if (RTCHECK(ok_address(m, v))) { /* split */
-      mchunkptr r = chunk_plus_offset(v, nb);
-      assert(chunksize(v) == rsize + nb);
-      if (RTCHECK(ok_next(v, r))) {
-        unlink_large_chunk(m, v);
-        if (rsize < MIN_CHUNK_SIZE)
-          set_inuse_and_pinuse(m, v, (rsize + nb));
-        else {
-          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
-          set_size_and_pinuse_of_free_chunk(r, rsize);
-          insert_chunk(m, r, rsize);
-        }
-        return chunk2mem(v);
-      }
-    }
-    CORRUPTION_ERROR_ACTION(m);
-  }
-  return 0;
-}
-
-/* allocate a small request from the best fitting chunk in a treebin */
-static void* tmalloc_small(mstate m, size_t nb) {
-  tchunkptr t, v;
-  size_t rsize;
-  bindex_t i;
-  binmap_t leastbit = least_bit(m->treemap);
-  compute_bit2idx(leastbit, i);
-
-  v = t = *treebin_at(m, i);
-  rsize = chunksize(t) - nb;
-
-  while ((t = leftmost_child(t)) != 0) {
-    size_t trem = chunksize(t) - nb;
-    if (trem < rsize) {
-      rsize = trem;
-      v = t;
-    }
-  }
-
-  if (RTCHECK(ok_address(m, v))) {
-    mchunkptr r = chunk_plus_offset(v, nb);
-    assert(chunksize(v) == rsize + nb);
-    if (RTCHECK(ok_next(v, r))) {
-      unlink_large_chunk(m, v);
-      if (rsize < MIN_CHUNK_SIZE)
-        set_inuse_and_pinuse(m, v, (rsize + nb));
-      else {
-        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        replace_dv(m, r, rsize);
-      }
-      return chunk2mem(v);
-    }
-  }
-
-  CORRUPTION_ERROR_ACTION(m);
-  return 0;
-}
-
-/* --------------------------- realloc support --------------------------- */
-
-static void* internal_realloc(mstate m, void* oldmem, size_t bytes) {
-  if (bytes >= MAX_REQUEST) {
-    MALLOC_FAILURE_ACTION;
-    return 0;
-  }
-  if (!PREACTION(m)) {
-    mchunkptr oldp = mem2chunk(oldmem);
-    size_t oldsize = chunksize(oldp);
-    mchunkptr next = chunk_plus_offset(oldp, oldsize);
-    mchunkptr newp = 0;
-    void* extra = 0;
-
-    /* Try to either shrink or extend into top. Else malloc-copy-free */
-
-    if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) &&
-                ok_next(oldp, next) && ok_pinuse(next))) {
-      size_t nb = request2size(bytes);
-      if (is_mmapped(oldp))
-        newp = mmap_resize(m, oldp, nb);
-      else if (oldsize >= nb) { /* already big enough */
-        size_t rsize = oldsize - nb;
-        newp = oldp;
-        if (rsize >= MIN_CHUNK_SIZE) {
-          mchunkptr remainder = chunk_plus_offset(newp, nb);
-          set_inuse(m, newp, nb);
-          set_inuse(m, remainder, rsize);
-          extra = chunk2mem(remainder);
-        }
-      }
-      else if (next == m->top && oldsize + m->topsize > nb) {
-        /* Expand into top */
-        size_t newsize = oldsize + m->topsize;
-        size_t newtopsize = newsize - nb;
-        mchunkptr newtop = chunk_plus_offset(oldp, nb);
-        set_inuse(m, oldp, nb);
-        newtop->head = newtopsize |PINUSE_BIT;
-        m->top = newtop;
-        m->topsize = newtopsize;
-        newp = oldp;
-      }
-    }
-    else {
-      USAGE_ERROR_ACTION(m, oldmem);
-      POSTACTION(m);
-      return 0;
-    }
-
-    POSTACTION(m);
-
-    if (newp != 0) {
-      if (extra != 0) {
-        internal_free(m, extra);
-      }
-      check_inuse_chunk(m, newp);
-      return chunk2mem(newp);
-    }
-    else {
-      void* newmem = internal_malloc(m, bytes);
-      if (newmem != 0) {
-        size_t oc = oldsize - overhead_for(oldp);
-        memcpy(newmem, oldmem, (oc < bytes)? oc : bytes);
-        internal_free(m, oldmem);
-      }
-      return newmem;
-    }
-  }
-  return 0;
-}
-
-/* --------------------------- memalign support -------------------------- */
-
-static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
-  if (alignment <= MALLOC_ALIGNMENT)    /* Can just use malloc */
-    return internal_malloc(m, bytes);
-  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
-    alignment = MIN_CHUNK_SIZE;
-  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
-    size_t a = MALLOC_ALIGNMENT << 1;
-    while (a < alignment) a <<= 1;
-    alignment = a;
-  }
-
-  if (bytes >= MAX_REQUEST - alignment) {
-    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
-      MALLOC_FAILURE_ACTION;
-    }
-  }
-  else {
-    size_t nb = request2size(bytes);
-    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
-    char* mem = (char*)internal_malloc(m, req);
-    if (mem != 0) {
-      void* leader = 0;
-      void* trailer = 0;
-      mchunkptr p = mem2chunk(mem);
-
-      if (PREACTION(m)) return 0;
-      if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */
-        /*
-          Find an aligned spot inside chunk.  Since we need to give
-          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
-          the first calculation places us at a spot with less than
-          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
-          We've allocated enough total room so that this is always
-          possible.
-        */
-        char* br = (char*)mem2chunk((size_t)(((size_t)(mem +
-                                                       alignment -
-                                                       SIZE_T_ONE)) &
-                                             -alignment));
-        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
-          br : br+alignment;
-        mchunkptr newp = (mchunkptr)pos;
-        size_t leadsize = pos - (char*)(p);
-        size_t newsize = chunksize(p) - leadsize;
-
-        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
-          newp->prev_foot = p->prev_foot + leadsize;
-          newp->head = (newsize|CINUSE_BIT);
-        }
-        else { /* Otherwise, give back leader, use the rest */
-          set_inuse(m, newp, newsize);
-          set_inuse(m, p, leadsize);
-          leader = chunk2mem(p);
-        }
-        p = newp;
-      }
-
-      /* Give back spare room at the end */
-      if (!is_mmapped(p)) {
-        size_t size = chunksize(p);
-        if (size > nb + MIN_CHUNK_SIZE) {
-          size_t remainder_size = size - nb;
-          mchunkptr remainder = chunk_plus_offset(p, nb);
-          set_inuse(m, p, nb);
-          set_inuse(m, remainder, remainder_size);
-          trailer = chunk2mem(remainder);
-        }
-      }
-
-      assert (chunksize(p) >= nb);
-      assert((((size_t)(chunk2mem(p))) % alignment) == 0);
-      check_inuse_chunk(m, p);
-      POSTACTION(m);
-      if (leader != 0) {
-        internal_free(m, leader);
-      }
-      if (trailer != 0) {
-        internal_free(m, trailer);
-      }
-      return chunk2mem(p);
-    }
-  }
-  return 0;
-}
-
-/* ------------------------ comalloc/coalloc support --------------------- */
-
-static void** ialloc(mstate m,
-                     size_t n_elements,
-                     size_t* sizes,
-                     int opts,
-                     void* chunks[]) {
-  /*
-    This provides common support for independent_X routines, handling
-    all of the combinations that can result.
-
-    The opts arg has:
-    bit 0 set if all elements are same size (using sizes[0])
-    bit 1 set if elements should be zeroed
-  */
-
-  size_t    element_size;   /* chunksize of each element, if all same */
-  size_t    contents_size;  /* total size of elements */
-  size_t    array_size;     /* request size of pointer array */
-  void*     mem;            /* malloced aggregate space */
-  mchunkptr p;              /* corresponding chunk */
-  size_t    remainder_size; /* remaining bytes while splitting */
-  void**    marray;         /* either "chunks" or malloced ptr array */
-  mchunkptr array_chunk;    /* chunk for malloced ptr array */
-  flag_t    was_enabled;    /* to disable mmap */
-  size_t    size;
-  size_t    i;
-
-  /* compute array length, if needed */
-  if (chunks != 0) {
-    if (n_elements == 0)
-      return chunks; /* nothing to do */
-    marray = chunks;
-    array_size = 0;
-  }
-  else {
-    /* if empty req, must still return chunk representing empty array */
-    if (n_elements == 0)
-      return (void**)internal_malloc(m, 0);
-    marray = 0;
-    array_size = request2size(n_elements * (sizeof(void*)));
-  }
-
-  /* compute total element size */
-  if (opts & 0x1) { /* all-same-size */
-    element_size = request2size(*sizes);
-    contents_size = n_elements * element_size;
-  }
-  else { /* add up all the sizes */
-    element_size = 0;
-    contents_size = 0;
-    for (i = 0; i != n_elements; ++i)
-      contents_size += request2size(sizes[i]);
-  }
-
-  size = contents_size + array_size;
-
-  /*
-     Allocate the aggregate chunk.  First disable direct-mmapping so
-     malloc won't use it, since we would not be able to later
-     free/realloc space internal to a segregated mmap region.
-  */
-  was_enabled = use_mmap(m);
-  disable_mmap(m);
-  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
-  if (was_enabled)
-    enable_mmap(m);
-  if (mem == 0)
-    return 0;
-
-  if (PREACTION(m)) return 0;
-  p = mem2chunk(mem);
-  remainder_size = chunksize(p);
-
-  assert(!is_mmapped(p));
-
-  if (opts & 0x2) {       /* optionally clear the elements */
-    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
-  }
-
-  /* If not provided, allocate the pointer array as final part of chunk */
-  if (marray == 0) {
-    size_t  array_chunk_size;
-    array_chunk = chunk_plus_offset(p, contents_size);
-    array_chunk_size = remainder_size - contents_size;
-    marray = (void**) (chunk2mem(array_chunk));
-    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
-    remainder_size = contents_size;
-  }
-
-  /* split out elements */
-  for (i = 0; ; ++i) {
-    marray[i] = chunk2mem(p);
-    if (i != n_elements-1) {
-      if (element_size != 0)
-        size = element_size;
-      else
-        size = request2size(sizes[i]);
-      remainder_size -= size;
-      set_size_and_pinuse_of_inuse_chunk(m, p, size);
-      p = chunk_plus_offset(p, size);
-    }
-    else { /* the final element absorbs any overallocation slop */
-      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
-      break;
-    }
-  }
-
-#if DEBUG
-  if (marray != chunks) {
-    /* final element must have exactly exhausted chunk */
-    if (element_size != 0) {
-      assert(remainder_size == element_size);
-    }
-    else {
-      assert(remainder_size == request2size(sizes[i]));
-    }
-    check_inuse_chunk(m, mem2chunk(marray));
-  }
-  for (i = 0; i != n_elements; ++i)
-    check_inuse_chunk(m, mem2chunk(marray[i]));
-
-#endif /* DEBUG */
-
-  POSTACTION(m);
-  return marray;
-}
-
-
-/* -------------------------- public routines ---------------------------- */
-
-#if !ONLY_MSPACES
-
-void* dlmalloc(size_t bytes) {
-  /*
-     Basic algorithm:
-     If a small request (< 256 bytes minus per-chunk overhead):
-       1. If one exists, use a remainderless chunk in associated smallbin.
-          (Remainderless means that there are too few excess bytes to
-          represent as a chunk.)
-       2. If it is big enough, use the dv chunk, which is normally the
-          chunk adjacent to the one used for the most recent small request.
-       3. If one exists, split the smallest available chunk in a bin,
-          saving remainder in dv.
-       4. If it is big enough, use the top chunk.
-       5. If available, get memory from system and use it
-     Otherwise, for a large request:
-       1. Find the smallest available binned chunk that fits, and use it
-          if it is better fitting than dv chunk, splitting if necessary.
-       2. If better fitting than any binned chunk, use the dv chunk.
-       3. If it is big enough, use the top chunk.
-       4. If request size >= mmap threshold, try to directly mmap this chunk.
-       5. If available, get memory from system and use it
-
-     The ugly goto's here ensure that postaction occurs along all paths.
-  */
-
-  if (!PREACTION(gm)) {
-    void* mem;
-    size_t nb;
-    if (bytes <= MAX_SMALL_REQUEST) {
-      bindex_t idx;
-      binmap_t smallbits;
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
-      idx = small_index(nb);
-      smallbits = gm->smallmap >> idx;
-
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
-        mchunkptr b, p;
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
-        b = smallbin_at(gm, idx);
-        p = b->fd;
-        assert(chunksize(p) == small_index2size(idx));
-        unlink_first_small_chunk(gm, b, p, idx);
-        set_inuse_and_pinuse(gm, p, small_index2size(idx));
-        mem = chunk2mem(p);
-        check_malloced_chunk(gm, mem, nb);
-        goto postaction;
-      }
-
-      else if (nb > gm->dvsize) {
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
-          mchunkptr b, p, r;
-          size_t rsize;
-          bindex_t i;
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
-          binmap_t leastbit = least_bit(leftbits);
-          compute_bit2idx(leastbit, i);
-          b = smallbin_at(gm, i);
-          p = b->fd;
-          assert(chunksize(p) == small_index2size(i));
-          unlink_first_small_chunk(gm, b, p, i);
-          rsize = small_index2size(i) - nb;
-          /* Fit here cannot be remainderless if 4byte sizes */
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
-            set_inuse_and_pinuse(gm, p, small_index2size(i));
-          else {
-            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-            r = chunk_plus_offset(p, nb);
-            set_size_and_pinuse_of_free_chunk(r, rsize);
-            replace_dv(gm, r, rsize);
-          }
-          mem = chunk2mem(p);
-          check_malloced_chunk(gm, mem, nb);
-          goto postaction;
-        }
-
-        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
-          check_malloced_chunk(gm, mem, nb);
-          goto postaction;
-        }
-      }
-    }
-    else if (bytes >= MAX_REQUEST)
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
-    else {
-      nb = pad_request(bytes);
-      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
-        check_malloced_chunk(gm, mem, nb);
-        goto postaction;
-      }
-    }
-
-    if (nb <= gm->dvsize) {
-      size_t rsize = gm->dvsize - nb;
-      mchunkptr p = gm->dv;
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
-        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
-        gm->dvsize = rsize;
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-      }
-      else { /* exhaust dv */
-        size_t dvs = gm->dvsize;
-        gm->dvsize = 0;
-        gm->dv = 0;
-        set_inuse_and_pinuse(gm, p, dvs);
-      }
-      mem = chunk2mem(p);
-      check_malloced_chunk(gm, mem, nb);
-      goto postaction;
-    }
-
-    else if (nb < gm->topsize) { /* Split top */
-      size_t rsize = gm->topsize -= nb;
-      mchunkptr p = gm->top;
-      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
-      mem = chunk2mem(p);
-      check_top_chunk(gm, gm->top);
-      check_malloced_chunk(gm, mem, nb);
-      goto postaction;
-    }
-
-    mem = sys_alloc(gm, nb);
-
-  postaction:
-    POSTACTION(gm);
-    return mem;
-  }
-
-  return 0;
-}
-
-void dlfree(void* mem) {
-  /*
-     Consolidate freed chunks with preceeding or succeeding bordering
-     free chunks, if they exist, and then place in a bin.  Intermixed
-     with special cases for top, dv, mmapped chunks, and usage errors.
-  */
-
-  if (mem != 0) {
-    mchunkptr p  = mem2chunk(mem);
-#if FOOTERS
-    mstate fm = get_mstate_for(p);
-    if (!ok_magic(fm)) {
-      USAGE_ERROR_ACTION(fm, p);
-      return;
-    }
-#else /* FOOTERS */
-#define fm gm
-#endif /* FOOTERS */
-    if (!PREACTION(fm)) {
-      check_inuse_chunk(fm, p);
-      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
-        size_t psize = chunksize(p);
-        mchunkptr next = chunk_plus_offset(p, psize);
-        if (!pinuse(p)) {
-          size_t prevsize = p->prev_foot;
-          if ((prevsize & IS_MMAPPED_BIT) != 0) {
-            prevsize &= ~IS_MMAPPED_BIT;
-            psize += prevsize + MMAP_FOOT_PAD;
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
-              fm->footprint -= psize;
-            goto postaction;
-          }
-          else {
-            mchunkptr prev = chunk_minus_offset(p, prevsize);
-            psize += prevsize;
-            p = prev;
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
-              if (p != fm->dv) {
-                unlink_chunk(fm, p, prevsize);
-              }
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
-                fm->dvsize = psize;
-                set_free_with_pinuse(p, psize, next);
-                goto postaction;
-              }
-            }
-            else
-              goto erroraction;
-          }
-        }
-
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
-          if (!cinuse(next)) {  /* consolidate forward */
-            if (next == fm->top) {
-              size_t tsize = fm->topsize += psize;
-              fm->top = p;
-              p->head = tsize | PINUSE_BIT;
-              if (p == fm->dv) {
-                fm->dv = 0;
-                fm->dvsize = 0;
-              }
-              if (should_trim(fm, tsize))
-                sys_trim(fm, 0);
-              goto postaction;
-            }
-            else if (next == fm->dv) {
-              size_t dsize = fm->dvsize += psize;
-              fm->dv = p;
-              set_size_and_pinuse_of_free_chunk(p, dsize);
-              goto postaction;
-            }
-            else {
-              size_t nsize = chunksize(next);
-              psize += nsize;
-              unlink_chunk(fm, next, nsize);
-              set_size_and_pinuse_of_free_chunk(p, psize);
-              if (p == fm->dv) {
-                fm->dvsize = psize;
-                goto postaction;
-              }
-            }
-          }
-          else
-            set_free_with_pinuse(p, psize, next);
-          insert_chunk(fm, p, psize);
-          check_free_chunk(fm, p);
-          goto postaction;
-        }
-      }
-    erroraction:
-      USAGE_ERROR_ACTION(fm, p);
-    postaction:
-      POSTACTION(fm);
-    }
-  }
-#if !FOOTERS
-#undef fm
-#endif /* FOOTERS */
-}
-
-void* dlcalloc(size_t n_elements, size_t elem_size) {
-  void* mem;
-  size_t req = 0;
-  if (n_elements != 0) {
-    req = n_elements * elem_size;
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
-        (req / n_elements != elem_size))
-      req = MAX_SIZE_T; /* force downstream failure on overflow */
-  }
-  mem = dlmalloc(req);
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
-    memset(mem, 0, req);
-  return mem;
-}
-
-void* dlrealloc(void* oldmem, size_t bytes) {
-  if (oldmem == 0)
-    return dlmalloc(bytes);
-#ifdef REALLOC_ZERO_BYTES_FREES
-  if (bytes == 0) {
-    dlfree(oldmem);
-    return 0;
-  }
-#endif /* REALLOC_ZERO_BYTES_FREES */
-  else {
-#if ! FOOTERS
-    mstate m = gm;
-#else /* FOOTERS */
-    mstate m = get_mstate_for(mem2chunk(oldmem));
-    if (!ok_magic(m)) {
-      USAGE_ERROR_ACTION(m, oldmem);
-      return 0;
-    }
-#endif /* FOOTERS */
-    return internal_realloc(m, oldmem, bytes);
-  }
-}
-
-void* dlmemalign(size_t alignment, size_t bytes) {
-  return internal_memalign(gm, alignment, bytes);
-}
-
-void** dlindependent_calloc(size_t n_elements, size_t elem_size,
-                                 void* chunks[]) {
-  size_t sz = elem_size; /* serves as 1-element array */
-  return ialloc(gm, n_elements, &sz, 3, chunks);
-}
-
-void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
-                                   void* chunks[]) {
-  return ialloc(gm, n_elements, sizes, 0, chunks);
-}
-
-void* dlvalloc(size_t bytes) {
-  size_t pagesz;
-  init_mparams();
-  pagesz = mparams.page_size;
-  return dlmemalign(pagesz, bytes);
-}
-
-void* dlpvalloc(size_t bytes) {
-  size_t pagesz;
-  init_mparams();
-  pagesz = mparams.page_size;
-  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
-}
-
-int dlmalloc_trim(size_t pad) {
-  int result = 0;
-  if (!PREACTION(gm)) {
-    result = sys_trim(gm, pad);
-    POSTACTION(gm);
-  }
-  return result;
-}
-
-size_t dlmalloc_footprint(void) {
-  return gm->footprint;
-}
-
-size_t dlmalloc_max_footprint(void) {
-  return gm->max_footprint;
-}
-
-#if !NO_MALLINFO
-struct mallinfo dlmallinfo(void) {
-  return internal_mallinfo(gm);
-}
-#endif /* NO_MALLINFO */
-
-void dlmalloc_stats() {
-  internal_malloc_stats(gm);
-}
-
-size_t dlmalloc_usable_size(void* mem) {
-  if (mem != 0) {
-    mchunkptr p = mem2chunk(mem);
-    if (cinuse(p))
-      return chunksize(p) - overhead_for(p);
-  }
-  return 0;
-}
-
-int dlmallopt(int param_number, int value) {
-  return change_mparam(param_number, value);
-}
-
-#endif /* !ONLY_MSPACES */
-
-/* ----------------------------- user mspaces ---------------------------- */
-
-#if MSPACES
-
-static mstate init_user_mstate(char* tbase, size_t tsize) {
-  size_t msize = pad_request(sizeof(struct malloc_state));
-  mchunkptr mn;
-  mchunkptr msp = align_as_chunk(tbase);
-  mstate m = (mstate)(chunk2mem(msp));
-  memset(m, 0, msize);
-  INITIAL_LOCK(&m->mutex);
-  msp->head = (msize|PINUSE_BIT|CINUSE_BIT);
-  m->seg.base = m->least_addr = tbase;
-  m->seg.size = m->footprint = m->max_footprint = tsize;
-  m->magic = mparams.magic;
-  m->mflags = mparams.default_mflags;
-  disable_contiguous(m);
-  init_bins(m);
-  mn = next_chunk(mem2chunk(m));
-  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
-  check_top_chunk(m, m->top);
-  return m;
-}
-
-mspace create_mspace(size_t capacity, int locked) {
-  mstate m = 0;
-  size_t msize = pad_request(sizeof(struct malloc_state));
-  init_mparams(); /* Ensure pagesize etc initialized */
-
-  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
-    size_t rs = ((capacity == 0)? mparams.granularity :
-                 (capacity + TOP_FOOT_SIZE + msize));
-    size_t tsize = granularity_align(rs);
-    char* tbase = (char*)(CALL_MMAP(tsize));
-    if (tbase != CMFAIL) {
-      m = init_user_mstate(tbase, tsize);
-      m->seg.sflags = IS_MMAPPED_BIT;
-      set_lock(m, locked);
-    }
-  }
-  return (mspace)m;
-}
-
-mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
-  mstate m = 0;
-  size_t msize = pad_request(sizeof(struct malloc_state));
-  init_mparams(); /* Ensure pagesize etc initialized */
-
-  if (capacity > msize + TOP_FOOT_SIZE &&
-      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
-    m = init_user_mstate((char*)base, capacity);
-    m->seg.sflags = EXTERN_BIT;
-    set_lock(m, locked);
-  }
-  return (mspace)m;
-}
-
-size_t destroy_mspace(mspace msp) {
-  size_t freed = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    msegmentptr sp = &ms->seg;
-    while (sp != 0) {
-      char* base = sp->base;
-      size_t size = sp->size;
-      flag_t flag = sp->sflags;
-      sp = sp->next;
-      if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) &&
-          CALL_MUNMAP(base, size) == 0)
-        freed += size;
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return freed;
-}
-
-/*
-  mspace versions of routines are near-clones of the global
-  versions. This is not so nice but better than the alternatives.
-*/
-
-
-void* mspace_malloc(mspace msp, size_t bytes) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  if (!PREACTION(ms)) {
-    void* mem;
-    size_t nb;
-    if (bytes <= MAX_SMALL_REQUEST) {
-      bindex_t idx;
-      binmap_t smallbits;
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
-      idx = small_index(nb);
-      smallbits = ms->smallmap >> idx;
-
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
-        mchunkptr b, p;
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
-        b = smallbin_at(ms, idx);
-        p = b->fd;
-        assert(chunksize(p) == small_index2size(idx));
-        unlink_first_small_chunk(ms, b, p, idx);
-        set_inuse_and_pinuse(ms, p, small_index2size(idx));
-        mem = chunk2mem(p);
-        check_malloced_chunk(ms, mem, nb);
-        goto postaction;
-      }
-
-      else if (nb > ms->dvsize) {
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
-          mchunkptr b, p, r;
-          size_t rsize;
-          bindex_t i;
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
-          binmap_t leastbit = least_bit(leftbits);
-          compute_bit2idx(leastbit, i);
-          b = smallbin_at(ms, i);
-          p = b->fd;
-          assert(chunksize(p) == small_index2size(i));
-          unlink_first_small_chunk(ms, b, p, i);
-          rsize = small_index2size(i) - nb;
-          /* Fit here cannot be remainderless if 4byte sizes */
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
-            set_inuse_and_pinuse(ms, p, small_index2size(i));
-          else {
-            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-            r = chunk_plus_offset(p, nb);
-            set_size_and_pinuse_of_free_chunk(r, rsize);
-            replace_dv(ms, r, rsize);
-          }
-          mem = chunk2mem(p);
-          check_malloced_chunk(ms, mem, nb);
-          goto postaction;
-        }
-
-        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
-          check_malloced_chunk(ms, mem, nb);
-          goto postaction;
-        }
-      }
-    }
-    else if (bytes >= MAX_REQUEST)
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
-    else {
-      nb = pad_request(bytes);
-      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
-        check_malloced_chunk(ms, mem, nb);
-        goto postaction;
-      }
-    }
-
-    if (nb <= ms->dvsize) {
-      size_t rsize = ms->dvsize - nb;
-      mchunkptr p = ms->dv;
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
-        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
-        ms->dvsize = rsize;
-        set_size_and_pinuse_of_free_chunk(r, rsize);
-        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-      }
-      else { /* exhaust dv */
-        size_t dvs = ms->dvsize;
-        ms->dvsize = 0;
-        ms->dv = 0;
-        set_inuse_and_pinuse(ms, p, dvs);
-      }
-      mem = chunk2mem(p);
-      check_malloced_chunk(ms, mem, nb);
-      goto postaction;
-    }
-
-    else if (nb < ms->topsize) { /* Split top */
-      size_t rsize = ms->topsize -= nb;
-      mchunkptr p = ms->top;
-      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
-      r->head = rsize | PINUSE_BIT;
-      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
-      mem = chunk2mem(p);
-      check_top_chunk(ms, ms->top);
-      check_malloced_chunk(ms, mem, nb);
-      goto postaction;
-    }
-
-    mem = sys_alloc(ms, nb);
-
-  postaction:
-    POSTACTION(ms);
-    return mem;
-  }
-
-  return 0;
-}
-
-void mspace_free(mspace msp, void* mem) {
-  if (mem != 0) {
-    mchunkptr p  = mem2chunk(mem);
-#if FOOTERS
-    mstate fm = get_mstate_for(p);
-#else /* FOOTERS */
-    mstate fm = (mstate)msp;
-#endif /* FOOTERS */
-    if (!ok_magic(fm)) {
-      USAGE_ERROR_ACTION(fm, p);
-      return;
-    }
-    if (!PREACTION(fm)) {
-      check_inuse_chunk(fm, p);
-      if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) {
-        size_t psize = chunksize(p);
-        mchunkptr next = chunk_plus_offset(p, psize);
-        if (!pinuse(p)) {
-          size_t prevsize = p->prev_foot;
-          if ((prevsize & IS_MMAPPED_BIT) != 0) {
-            prevsize &= ~IS_MMAPPED_BIT;
-            psize += prevsize + MMAP_FOOT_PAD;
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
-              fm->footprint -= psize;
-            goto postaction;
-          }
-          else {
-            mchunkptr prev = chunk_minus_offset(p, prevsize);
-            psize += prevsize;
-            p = prev;
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
-              if (p != fm->dv) {
-                unlink_chunk(fm, p, prevsize);
-              }
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
-                fm->dvsize = psize;
-                set_free_with_pinuse(p, psize, next);
-                goto postaction;
-              }
-            }
-            else
-              goto erroraction;
-          }
-        }
-
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
-          if (!cinuse(next)) {  /* consolidate forward */
-            if (next == fm->top) {
-              size_t tsize = fm->topsize += psize;
-              fm->top = p;
-              p->head = tsize | PINUSE_BIT;
-              if (p == fm->dv) {
-                fm->dv = 0;
-                fm->dvsize = 0;
-              }
-              if (should_trim(fm, tsize))
-                sys_trim(fm, 0);
-              goto postaction;
-            }
-            else if (next == fm->dv) {
-              size_t dsize = fm->dvsize += psize;
-              fm->dv = p;
-              set_size_and_pinuse_of_free_chunk(p, dsize);
-              goto postaction;
-            }
-            else {
-              size_t nsize = chunksize(next);
-              psize += nsize;
-              unlink_chunk(fm, next, nsize);
-              set_size_and_pinuse_of_free_chunk(p, psize);
-              if (p == fm->dv) {
-                fm->dvsize = psize;
-                goto postaction;
-              }
-            }
-          }
-          else
-            set_free_with_pinuse(p, psize, next);
-          insert_chunk(fm, p, psize);
-          check_free_chunk(fm, p);
-          goto postaction;
-        }
-      }
-    erroraction:
-      USAGE_ERROR_ACTION(fm, p);
-    postaction:
-      POSTACTION(fm);
-    }
-  }
-}
-
-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
-  void* mem;
-  size_t req = 0;
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  if (n_elements != 0) {
-    req = n_elements * elem_size;
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
-        (req / n_elements != elem_size))
-      req = MAX_SIZE_T; /* force downstream failure on overflow */
-  }
-  mem = internal_malloc(ms, req);
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
-    memset(mem, 0, req);
-  return mem;
-}
-
-void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
-  if (oldmem == 0)
-    return mspace_malloc(msp, bytes);
-#ifdef REALLOC_ZERO_BYTES_FREES
-  if (bytes == 0) {
-    mspace_free(msp, oldmem);
-    return 0;
-  }
-#endif /* REALLOC_ZERO_BYTES_FREES */
-  else {
-#if FOOTERS
-    mchunkptr p  = mem2chunk(oldmem);
-    mstate ms = get_mstate_for(p);
-#else /* FOOTERS */
-    mstate ms = (mstate)msp;
-#endif /* FOOTERS */
-    if (!ok_magic(ms)) {
-      USAGE_ERROR_ACTION(ms,ms);
-      return 0;
-    }
-    return internal_realloc(ms, oldmem, bytes);
-  }
-}
-
-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  return internal_memalign(ms, alignment, bytes);
-}
-
-void** mspace_independent_calloc(mspace msp, size_t n_elements,
-                                 size_t elem_size, void* chunks[]) {
-  size_t sz = elem_size; /* serves as 1-element array */
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  return ialloc(ms, n_elements, &sz, 3, chunks);
-}
-
-void** mspace_independent_comalloc(mspace msp, size_t n_elements,
-                                   size_t sizes[], void* chunks[]) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-    return 0;
-  }
-  return ialloc(ms, n_elements, sizes, 0, chunks);
-}
-
-int mspace_trim(mspace msp, size_t pad) {
-  int result = 0;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    if (!PREACTION(ms)) {
-      result = sys_trim(ms, pad);
-      POSTACTION(ms);
-    }
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return result;
-}
-
-void mspace_malloc_stats(mspace msp) {
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    internal_malloc_stats(ms);
-  }
-  else {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-}
-
-size_t mspace_footprint(mspace msp) {
-  size_t result;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    result = ms->footprint;
-  }
-  USAGE_ERROR_ACTION(ms,ms);
-  return result;
-}
-
-
-size_t mspace_max_footprint(mspace msp) {
-  size_t result;
-  mstate ms = (mstate)msp;
-  if (ok_magic(ms)) {
-    result = ms->max_footprint;
-  }
-  USAGE_ERROR_ACTION(ms,ms);
-  return result;
-}
-
-
-#if !NO_MALLINFO
-struct mallinfo mspace_mallinfo(mspace msp) {
-  mstate ms = (mstate)msp;
-  if (!ok_magic(ms)) {
-    USAGE_ERROR_ACTION(ms,ms);
-  }
-  return internal_mallinfo(ms);
-}
-#endif /* NO_MALLINFO */
-
-int mspace_mallopt(int param_number, int value) {
-  return change_mparam(param_number, value);
-}
-
-#endif /* MSPACES */
-
-/* -------------------- Alternative MORECORE functions ------------------- */
-
-/*
-  Guidelines for creating a custom version of MORECORE:
-
-  * For best performance, MORECORE should allocate in multiples of pagesize.
-  * MORECORE may allocate more memory than requested. (Or even less,
-      but this will usually result in a malloc failure.)
-  * MORECORE must not allocate memory when given argument zero, but
-      instead return one past the end address of memory from previous
-      nonzero call.
-  * For best performance, consecutive calls to MORECORE with positive
-      arguments should return increasing addresses, indicating that
-      space has been contiguously extended.
-  * Even though consecutive calls to MORECORE need not return contiguous
-      addresses, it must be OK for malloc'ed chunks to span multiple
-      regions in those cases where they do happen to be contiguous.
-  * MORECORE need not handle negative arguments -- it may instead
-      just return MFAIL when given negative arguments.
-      Negative arguments are always multiples of pagesize. MORECORE
-      must not misinterpret negative args as large positive unsigned
-      args. You can suppress all such calls from even occurring by defining
-      MORECORE_CANNOT_TRIM,
-
-  As an example alternative MORECORE, here is a custom allocator
-  kindly contributed for pre-OSX macOS.  It uses virtually but not
-  necessarily physically contiguous non-paged memory (locked in,
-  present and won't get swapped out).  You can use it by uncommenting
-  this section, adding some #includes, and setting up the appropriate
-  defines above:
-
-      #define MORECORE osMoreCore
-
-  There is also a shutdown routine that should somehow be called for
-  cleanup upon program exit.
-
-  #define MAX_POOL_ENTRIES 100
-  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
-  static int next_os_pool;
-  void *our_os_pools[MAX_POOL_ENTRIES];
-
-  void *osMoreCore(int size)
-  {
-    void *ptr = 0;
-    static void *sbrk_top = 0;
-
-    if (size > 0)
-    {
-      if (size < MINIMUM_MORECORE_SIZE)
-         size = MINIMUM_MORECORE_SIZE;
-      if (CurrentExecutionLevel() == kTaskLevel)
-         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
-      if (ptr == 0)
-      {
-        return (void *) MFAIL;
-      }
-      // save ptrs so they can be freed during cleanup
-      our_os_pools[next_os_pool] = ptr;
-      next_os_pool++;
-      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
-      sbrk_top = (char *) ptr + size;
-      return ptr;
-    }
-    else if (size < 0)
-    {
-      // we don't currently support shrink behavior
-      return (void *) MFAIL;
-    }
-    else
-    {
-      return sbrk_top;
-    }
-  }
-
-  // cleanup any allocated memory pools
-  // called as last thing before shutting down driver
-
-  void osCleanupMem(void)
-  {
-    void **ptr;
-
-    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
-      if (*ptr)
-      {
-         PoolDeallocate(*ptr);
-         *ptr = 0;
-      }
-  }
-
-*/
-
-
-/* -----------------------------------------------------------------------
-History:
-    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
-      * Add max_footprint functions
-      * Ensure all appropriate literals are size_t
-      * Fix conditional compilation problem for some #define settings
-      * Avoid concatenating segments with the one provided
-        in create_mspace_with_base
-      * Rename some variables to avoid compiler shadowing warnings
-      * Use explicit lock initialization.
-      * Better handling of sbrk interference.
-      * Simplify and fix segment insertion, trimming and mspace_destroy
-      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
-      * Thanks especially to Dennis Flanagan for help on these.
-
-    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
-      * Fix memalign brace error.
-
-    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
-      * Fix improper #endif nesting in C++
-      * Add explicit casts needed for C++
-
-    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
-      * Use trees for large bins
-      * Support mspaces
-      * Use segments to unify sbrk-based and mmap-based system allocation,
-        removing need for emulation on most platforms without sbrk.
-      * Default safety checks
-      * Optional footer checks. Thanks to William Robertson for the idea.
-      * Internal code refactoring
-      * Incorporate suggestions and platform-specific changes.
-        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
-        Aaron Bachmann,  Emery Berger, and others.
-      * Speed up non-fastbin processing enough to remove fastbins.
-      * Remove useless cfree() to avoid conflicts with other apps.
-      * Remove internal memcpy, memset. Compilers handle builtins better.
-      * Remove some options that no one ever used and rename others.
-
-    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
-      * Fix malloc_state bitmap array misdeclaration
-
-    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
-      * Allow tuning of FIRST_SORTED_BIN_SIZE
-      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
-      * Better detection and support for non-contiguousness of MORECORE.
-        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
-      * Bypass most of malloc if no frees. Thanks To Emery Berger.
-      * Fix freeing of old top non-contiguous chunk im sysmalloc.
-      * Raised default trim and map thresholds to 256K.
-      * Fix mmap-related #defines. Thanks to Lubos Lunak.
-      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
-      * Branch-free bin calculation
-      * Default trim and mmap thresholds now 256K.
-
-    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
-      * Introduce independent_comalloc and independent_calloc.
-        Thanks to Michael Pachos for motivation and help.
-      * Make optional .h file available
-      * Allow > 2GB requests on 32bit systems.
-      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
-        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
-        and Anonymous.
-      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
-        helping test this.)
-      * memalign: check alignment arg
-      * realloc: don't try to shift chunks backwards, since this
-        leads to  more fragmentation in some programs and doesn't
-        seem to help in any others.
-      * Collect all cases in malloc requiring system memory into sysmalloc
-      * Use mmap as backup to sbrk
-      * Place all internal state in malloc_state
-      * Introduce fastbins (although similar to 2.5.1)
-      * Many minor tunings and cosmetic improvements
-      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
-      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
-        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
-      * Include errno.h to support default failure action.
-
-    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
-      * return null for negative arguments
-      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
-         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
-          (e.g. WIN32 platforms)
-         * Cleanup header file inclusion for WIN32 platforms
-         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
-         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
-           memory allocation routines
-         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
-         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
-           usage of 'assert' in non-WIN32 code
-         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
-           avoid infinite loop
-      * Always call 'fREe()' rather than 'free()'
-
-    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
-      * Fixed ordering problem with boundary-stamping
-
-    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
-      * Added pvalloc, as recommended by H.J. Liu
-      * Added 64bit pointer support mainly from Wolfram Gloger
-      * Added anonymously donated WIN32 sbrk emulation
-      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
-      * malloc_extend_top: fix mask error that caused wastage after
-        foreign sbrks
-      * Add linux mremap support code from HJ Liu
-
-    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
-      * Integrated most documentation with the code.
-      * Add support for mmap, with help from
-        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
-      * Use last_remainder in more cases.
-      * Pack bins using idea from  colin@nyx10.cs.du.edu
-      * Use ordered bins instead of best-fit threshhold
-      * Eliminate block-local decls to simplify tracing and debugging.
-      * Support another case of realloc via move into top
-      * Fix error occuring when initial sbrk_base not word-aligned.
-      * Rely on page size for units instead of SBRK_UNIT to
-        avoid surprises about sbrk alignment conventions.
-      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
-        (raymond@es.ele.tue.nl) for the suggestion.
-      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
-      * More precautions for cases where other routines call sbrk,
-        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
-      * Added macros etc., allowing use in linux libc from
-        H.J. Lu (hjl@gnu.ai.mit.edu)
-      * Inverted this history list
-
-    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
-      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
-      * Removed all preallocation code since under current scheme
-        the work required to undo bad preallocations exceeds
-        the work saved in good cases for most test programs.
-      * No longer use return list or unconsolidated bins since
-        no scheme using them consistently outperforms those that don't
-        given above changes.
-      * Use best fit for very large chunks to prevent some worst-cases.
-      * Added some support for debugging
-
-    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
-      * Removed footers when chunks are in use. Thanks to
-        Paul Wilson (wilson@cs.texas.edu) for the suggestion.
-
-    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
-      * Added malloc_trim, with help from Wolfram Gloger
-        (wmglo@Dent.MED.Uni-Muenchen.DE).
-
-    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
-
-    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
-      * realloc: try to expand in both directions
-      * malloc: swap order of clean-bin strategy;
-      * realloc: only conditionally expand backwards
-      * Try not to scavenge used bins
-      * Use bin counts as a guide to preallocation
-      * Occasionally bin return list chunks in first scan
-      * Add a few optimizations from colin@nyx10.cs.du.edu
-
-    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
-      * faster bin computation & slightly different binning
-      * merged all consolidations to one part of malloc proper
-         (eliminating old malloc_find_space & malloc_clean_bin)
-      * Scan 2 returns chunks (not just 1)
-      * Propagate failure in realloc if malloc returns 0
-      * Add stuff to allow compilation on non-ANSI compilers
-          from kpv@research.att.com
-
-    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
-      * removed potential for odd address access in prev_chunk
-      * removed dependency on getpagesize.h
-      * misc cosmetics and a bit more internal documentation
-      * anticosmetics: mangled names in macros to evade debugger strangeness
-      * tested on sparc, hp-700, dec-mips, rs6000
-          with gcc & native cc (hp, dec only) allowing
-          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
-
-    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
-      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
-         structure of old version,  but most details differ.)
-
-*/
diff --git a/lib/dlmalloc.h b/lib/dlmalloc.h
deleted file mode 100644
index 197b36667..000000000
--- a/lib/dlmalloc.h
+++ /dev/null
@@ -1,1143 +0,0 @@
-#ifndef DLMALLOC_H

-#define DLMALLOC_H

-

-#define USE_DL_PREFIX

-

-/*

-

-#define FOOTERS 1

-#define DEBUG 1

-#define ABORT_ON_ASSERT_FAILURE 0

-*/

-

-/*

-  This is a version (aka dlmalloc) of malloc/free/realloc written by

-  Doug Lea and released to the public domain, as explained at

-  http://creativecommons.org/licenses/publicdomain.  Send questions,

-  comments, complaints, performance data, etc to dl@cs.oswego.edu

-

-* Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)

-

-   Note: There may be an updated version of this malloc obtainable at

-           ftp://gee.cs.oswego.edu/pub/misc/malloc.c

-         Check before installing!

-

-* Quickstart

-

-  This library is all in one file to simplify the most common usage:

-  ftp it, compile it (-O3), and link it into another program. All of

-  the compile-time options default to reasonable values for use on

-  most platforms.  You might later want to step through various

-  compile-time and dynamic tuning options.

-

-  For convenience, an include file for code using this malloc is at:

-     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h

-  You don't really need this .h file unless you call functions not

-  defined in your system include files.  The .h file contains only the

-  excerpts from this file needed for using this malloc on ANSI C/C++

-  systems, so long as you haven't changed compile-time options about

-  naming and tuning parameters.  If you do, then you can create your

-  own malloc.h that does include all settings by cutting at the point

-  indicated below. Note that you may already by default be using a C

-  library containing a malloc that is based on some version of this

-  malloc (for example in linux). You might still want to use the one

-  in this file to customize settings or to avoid overheads associated

-  with library versions.

-

-* Vital statistics:

-

-  Supported pointer/size_t representation:       4 or 8 bytes

-       size_t MUST be an unsigned type of the same width as

-       pointers. (If you are using an ancient system that declares

-       size_t as a signed type, or need it to be a different width

-       than pointers, you can use a previous release of this malloc

-       (e.g. 2.7.2) supporting these.)

-

-  Alignment:                                     8 bytes (default)

-       This suffices for nearly all current machines and C compilers.

-       However, you can define MALLOC_ALIGNMENT to be wider than this

-       if necessary (up to 128bytes), at the expense of using more space.

-

-  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)

-                                          8 or 16 bytes (if 8byte sizes)

-       Each malloced chunk has a hidden word of overhead holding size

-       and status information, and additional cross-check word

-       if FOOTERS is defined.

-

-  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)

-                          8-byte ptrs:  32 bytes    (including overhead)

-

-       Even a request for zero bytes (i.e., malloc(0)) returns a

-       pointer to something of the minimum allocatable size.

-       The maximum overhead wastage (i.e., number of extra bytes

-       allocated than were requested in malloc) is less than or equal

-       to the minimum size, except for requests >= mmap_threshold that

-       are serviced via mmap(), where the worst case wastage is about

-       32 bytes plus the remainder from a system page (the minimal

-       mmap unit); typically 4096 or 8192 bytes.

-

-  Security: static-safe; optionally more or less

-       The "security" of malloc refers to the ability of malicious

-       code to accentuate the effects of errors (for example, freeing

-       space that is not currently malloc'ed or overwriting past the

-       ends of chunks) in code that calls malloc.  This malloc

-       guarantees not to modify any memory locations below the base of

-       heap, i.e., static variables, even in the presence of usage

-       errors.  The routines additionally detect most improper frees

-       and reallocs.  All this holds as long as the static bookkeeping

-       for malloc itself is not corrupted by some other means.  This

-       is only one aspect of security -- these checks do not, and

-       cannot, detect all possible programming errors.

-

-       If FOOTERS is defined nonzero, then each allocated chunk

-       carries an additional check word to verify that it was malloced

-       from its space.  These check words are the same within each

-       execution of a program using malloc, but differ across

-       executions, so externally crafted fake chunks cannot be

-       freed. This improves security by rejecting frees/reallocs that

-       could corrupt heap memory, in addition to the checks preventing

-       writes to statics that are always on.  This may further improve

-       security at the expense of time and space overhead.  (Note that

-       FOOTERS may also be worth using with MSPACES.)

-

-       By default detected errors cause the program to abort (calling

-       "abort()"). You can override this to instead proceed past

-       errors by defining PROCEED_ON_ERROR.  In this case, a bad free

-       has no effect, and a malloc that encounters a bad address

-       caused by user overwrites will ignore the bad address by

-       dropping pointers and indices to all known memory. This may

-       be appropriate for programs that should continue if at all

-       possible in the face of programming errors, although they may

-       run out of memory because dropped memory is never reclaimed.

-

-       If you don't like either of these options, you can define

-       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything

-       else. And if if you are sure that your program using malloc has

-       no errors or vulnerabilities, you can define INSECURE to 1,

-       which might (or might not) provide a small performance improvement.

-

-  Thread-safety: NOT thread-safe unless USE_LOCKS defined

-       When USE_LOCKS is defined, each public call to malloc, free,

-       etc is surrounded with either a pthread mutex or a win32

-       spinlock (depending on WIN32). This is not especially fast, and

-       can be a major bottleneck.  It is designed only to provide

-       minimal protection in concurrent environments, and to provide a

-       basis for extensions.  If you are using malloc in a concurrent

-       program, consider instead using ptmalloc, which is derived from

-       a version of this malloc. (See http://www.malloc.de).

-

-  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP

-       This malloc can use unix sbrk or any emulation (invoked using

-       the CALL_MORECORE macro) and/or mmap/munmap or any emulation

-       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system

-       memory.  On most unix systems, it tends to work best if both

-       MORECORE and MMAP are enabled.  On Win32, it uses emulations

-       based on VirtualAlloc. It also uses common C library functions

-       like memset.

-

-  Compliance: I believe it is compliant with the Single Unix Specification

-       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably

-       others as well.

-

-* Overview of algorithms

-

-  This is not the fastest, most space-conserving, most portable, or

-  most tunable malloc ever written. However it is among the fastest

-  while also being among the most space-conserving, portable and

-  tunable.  Consistent balance across these factors results in a good

-  general-purpose allocator for malloc-intensive programs.

-

-  In most ways, this malloc is a best-fit allocator. Generally, it

-  chooses the best-fitting existing chunk for a request, with ties

-  broken in approximately least-recently-used order. (This strategy

-  normally maintains low fragmentation.) However, for requests less

-  than 256bytes, it deviates from best-fit when there is not an

-  exactly fitting available chunk by preferring to use space adjacent

-  to that used for the previous small request, as well as by breaking

-  ties in approximately most-recently-used order. (These enhance

-  locality of series of small allocations.)  And for very large requests

-  (>= 256Kb by default), it relies on system memory mapping

-  facilities, if supported.  (This helps avoid carrying around and

-  possibly fragmenting memory used only for large chunks.)

-

-  All operations (except malloc_stats and mallinfo) have execution

-  times that are bounded by a constant factor of the number of bits in

-  a size_t, not counting any clearing in calloc or copying in realloc,

-  or actions surrounding MORECORE and MMAP that have times

-  proportional to the number of non-contiguous regions returned by

-  system allocation routines, which is often just 1.

-

-  The implementation is not very modular and seriously overuses

-  macros. Perhaps someday all C compilers will do as good a job

-  inlining modular code as can now be done by brute-force expansion,

-  but now, enough of them seem not to.

-

-  Some compilers issue a lot of warnings about code that is

-  dead/unreachable only on some platforms, and also about intentional

-  uses of negation on unsigned types. All known cases of each can be

-  ignored.

-

-  For a longer but out of date high-level description, see

-     http://gee.cs.oswego.edu/dl/html/malloc.html

-

-* MSPACES

-  If MSPACES is defined, then in addition to malloc, free, etc.,

-  this file also defines mspace_malloc, mspace_free, etc. These

-  are versions of malloc routines that take an "mspace" argument

-  obtained using create_mspace, to control all internal bookkeeping.

-  If ONLY_MSPACES is defined, only these versions are compiled.

-  So if you would like to use this allocator for only some allocations,

-  and your system malloc for others, you can compile with

-  ONLY_MSPACES and then do something like...

-    static mspace mymspace = create_mspace(0,0); // for example

-    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)

-

-  (Note: If you only need one instance of an mspace, you can instead

-  use "USE_DL_PREFIX" to relabel the global malloc.)

-

-  You can similarly create thread-local allocators by storing

-  mspaces as thread-locals. For example:

-    static __thread mspace tlms = 0;

-    void*  tlmalloc(size_t bytes) {

-      if (tlms == 0) tlms = create_mspace(0, 0);

-      return mspace_malloc(tlms, bytes);

-    }

-    void  tlfree(void* mem) { mspace_free(tlms, mem); }

-

-  Unless FOOTERS is defined, each mspace is completely independent.

-  You cannot allocate from one and free to another (although

-  conformance is only weakly checked, so usage errors are not always

-  caught). If FOOTERS is defined, then each chunk carries around a tag

-  indicating its originating mspace, and frees are directed to their

-  originating spaces.

-

- -------------------------  Compile-time options ---------------------------

-

-Be careful in setting #define values for numerical constants of type

-size_t. On some systems, literal values are not automatically extended

-to size_t precision unless they are explicitly casted.

-

-WIN32                    default: defined if _WIN32 defined

-  Defining WIN32 sets up defaults for MS environment and compilers.

-  Otherwise defaults are for unix.

-

-MALLOC_ALIGNMENT         default: (size_t)8

-  Controls the minimum alignment for malloc'ed chunks.  It must be a

-  power of two and at least 8, even on machines for which smaller

-  alignments would suffice. It may be defined as larger than this

-  though. Note however that code and data structures are optimized for

-  the case of 8-byte alignment.

-

-MSPACES                  default: 0 (false)

-  If true, compile in support for independent allocation spaces.

-  This is only supported if HAVE_MMAP is true.

-

-ONLY_MSPACES             default: 0 (false)

-  If true, only compile in mspace versions, not regular versions.

-

-USE_LOCKS                default: 0 (false)

-  Causes each call to each public routine to be surrounded with

-  pthread or WIN32 mutex lock/unlock. (If set true, this can be

-  overridden on a per-mspace basis for mspace versions.)

-

-FOOTERS                  default: 0

-  If true, provide extra checking and dispatching by placing

-  information in the footers of allocated chunks. This adds

-  space and time overhead.

-

-INSECURE                 default: 0

-  If true, omit checks for usage errors and heap space overwrites.

-

-USE_DL_PREFIX            default: NOT defined

-  Causes compiler to prefix all public routines with the string 'dl'.

-  This can be useful when you only want to use this malloc in one part

-  of a program, using your regular system malloc elsewhere.

-

-ABORT                    default: defined as abort()

-  Defines how to abort on failed checks.  On most systems, a failed

-  check cannot die with an "assert" or even print an informative

-  message, because the underlying print routines in turn call malloc,

-  which will fail again.  Generally, the best policy is to simply call

-  abort(). It's not very useful to do more than this because many

-  errors due to overwriting will show up as address faults (null, odd

-  addresses etc) rather than malloc-triggered checks, so will also

-  abort.  Also, most compilers know that abort() does not return, so

-  can better optimize code conditionally calling it.

-

-PROCEED_ON_ERROR           default: defined as 0 (false)

-  Controls whether detected bad addresses cause them to bypassed

-  rather than aborting. If set, detected bad arguments to free and

-  realloc are ignored. And all bookkeeping information is zeroed out

-  upon a detected overwrite of freed heap space, thus losing the

-  ability to ever return it from malloc again, but enabling the

-  application to proceed. If PROCEED_ON_ERROR is defined, the

-  static variable malloc_corruption_error_count is compiled in

-  and can be examined to see if errors have occurred. This option

-  generates slower code than the default abort policy.

-

-DEBUG                    default: NOT defined

-  The DEBUG setting is mainly intended for people trying to modify

-  this code or diagnose problems when porting to new platforms.

-  However, it may also be able to better isolate user errors than just

-  using runtime checks.  The assertions in the check routines spell

-  out in more detail the assumptions and invariants underlying the

-  algorithms.  The checking is fairly extensive, and will slow down

-  execution noticeably. Calling malloc_stats or mallinfo with DEBUG

-  set will attempt to check every non-mmapped allocated and free chunk

-  in the course of computing the summaries.

-

-ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)

-  Debugging assertion failures can be nearly impossible if your

-  version of the assert macro causes malloc to be called, which will

-  lead to a cascade of further failures, blowing the runtime stack.

-  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),

-  which will usually make debugging easier.

-

-MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32

-  The action to take before "return 0" when malloc fails to be able to

-  return memory because there is none available.

-

-HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES

-  True if this system supports sbrk or an emulation of it.

-

-MORECORE                  default: sbrk

-  The name of the sbrk-style system routine to call to obtain more

-  memory.  See below for guidance on writing custom MORECORE

-  functions. The type of the argument to sbrk/MORECORE varies across

-  systems.  It cannot be size_t, because it supports negative

-  arguments, so it is normally the signed type of the same width as

-  size_t (sometimes declared as "intptr_t").  It doesn't much matter

-  though. Internally, we only call it with arguments less than half

-  the max value of a size_t, which should work across all reasonable

-  possibilities, although sometimes generating compiler warnings.  See

-  near the end of this file for guidelines for creating a custom

-  version of MORECORE.

-

-MORECORE_CONTIGUOUS       default: 1 (true)

-  If true, take advantage of fact that consecutive calls to MORECORE

-  with positive arguments always return contiguous increasing

-  addresses.  This is true of unix sbrk. It does not hurt too much to

-  set it true anyway, since malloc copes with non-contiguities.

-  Setting it false when definitely non-contiguous saves time

-  and possibly wasted space it would take to discover this though.

-

-MORECORE_CANNOT_TRIM      default: NOT defined

-  True if MORECORE cannot release space back to the system when given

-  negative arguments. This is generally necessary only if you are

-  using a hand-crafted MORECORE function that cannot handle negative

-  arguments.

-

-HAVE_MMAP                 default: 1 (true)

-  True if this system supports mmap or an emulation of it.  If so, and

-  HAVE_MORECORE is not true, MMAP is used for all system

-  allocation. If set and HAVE_MORECORE is true as well, MMAP is

-  primarily used to directly allocate very large blocks. It is also

-  used as a backup strategy in cases where MORECORE fails to provide

-  space from system. Note: A single call to MUNMAP is assumed to be

-  able to unmap memory that may have be allocated using multiple calls

-  to MMAP, so long as they are adjacent.

-

-HAVE_MREMAP               default: 1 on linux, else 0

-  If true realloc() uses mremap() to re-allocate large blocks and

-  extend or shrink allocation spaces.

-

-MMAP_CLEARS               default: 1 on unix

-  True if mmap clears memory so calloc doesn't need to. This is true

-  for standard unix mmap using /dev/zero.

-

-USE_BUILTIN_FFS            default: 0 (i.e., not used)

-  Causes malloc to use the builtin ffs() function to compute indices.

-  Some compilers may recognize and intrinsify ffs to be faster than the

-  supplied C version. Also, the case of x86 using gcc is special-cased

-  to an asm instruction, so is already as fast as it can be, and so

-  this setting has no effect. (On most x86s, the asm version is only

-  slightly faster than the C version.)

-

-malloc_getpagesize         default: derive from system includes, or 4096.

-  The system page size. To the extent possible, this malloc manages

-  memory from the system in page-size units.  This may be (and

-  usually is) a function rather than a constant. This is ignored

-  if WIN32, where page size is determined using getSystemInfo during

-  initialization.

-

-USE_DEV_RANDOM             default: 0 (i.e., not used)

-  Causes malloc to use /dev/random to initialize secure magic seed for

-  stamping footers. Otherwise, the current time is used.

-

-NO_MALLINFO                default: 0

-  If defined, don't compile "mallinfo". This can be a simple way

-  of dealing with mismatches between system declarations and

-  those in this file.

-

-MALLINFO_FIELD_TYPE        default: size_t

-  The type of the fields in the mallinfo struct. This was originally

-  defined as "int" in SVID etc, but is more usefully defined as

-  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set

-

-REALLOC_ZERO_BYTES_FREES    default: not defined

-  This should be set if a call to realloc with zero bytes should

-  be the same as a call to free. Some people think it should. Otherwise,

-  since this malloc returns a unique pointer for malloc(0), so does

-  realloc(p, 0).

-

-LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H

-LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H

-LACKS_STDLIB_H                default: NOT defined unless on WIN32

-  Define these if your system does not have these header files.

-  You might need to manually insert some of the declarations they provide.

-

-DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,

-                                system_info.dwAllocationGranularity in WIN32,

-                                otherwise 64K.

-      Also settable using mallopt(M_GRANULARITY, x)

-  The unit for allocating and deallocating memory from the system.  On

-  most systems with contiguous MORECORE, there is no reason to

-  make this more than a page. However, systems with MMAP tend to

-  either require or encourage larger granularities.  You can increase

-  this value to prevent system allocation functions to be called so

-  often, especially if they are slow.  The value must be at least one

-  page and must be a power of two.  Setting to 0 causes initialization

-  to either page size or win32 region size.  (Note: In previous

-  versions of malloc, the equivalent of this option was called

-  "TOP_PAD")

-

-DEFAULT_TRIM_THRESHOLD    default: 2MB

-      Also settable using mallopt(M_TRIM_THRESHOLD, x)

-  The maximum amount of unused top-most memory to keep before

-  releasing via malloc_trim in free().  Automatic trimming is mainly

-  useful in long-lived programs using contiguous MORECORE.  Because

-  trimming via sbrk can be slow on some systems, and can sometimes be

-  wasteful (in cases where programs immediately afterward allocate

-  more large chunks) the value should be high enough so that your

-  overall system performance would improve by releasing this much

-  memory.  As a rough guide, you might set to a value close to the

-  average size of a process (program) running on your system.

-  Releasing this much memory would allow such a process to run in

-  memory.  Generally, it is worth tuning trim thresholds when a

-  program undergoes phases where several large chunks are allocated

-  and released in ways that can reuse each other's storage, perhaps

-  mixed with phases where there are no such chunks at all. The trim

-  value must be greater than page size to have any useful effect.  To

-  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick

-  some people use of mallocing a huge space and then freeing it at

-  program startup, in an attempt to reserve system memory, doesn't

-  have the intended effect under automatic trimming, since that memory

-  will immediately be returned to the system.

-

-DEFAULT_MMAP_THRESHOLD       default: 256K

-      Also settable using mallopt(M_MMAP_THRESHOLD, x)

-  The request size threshold for using MMAP to directly service a

-  request. Requests of at least this size that cannot be allocated

-  using already-existing space will be serviced via mmap.  (If enough

-  normal freed space already exists it is used instead.)  Using mmap

-  segregates relatively large chunks of memory so that they can be

-  individually obtained and released from the host system. A request

-  serviced through mmap is never reused by any other request (at least

-  not directly; the system may just so happen to remap successive

-  requests to the same locations).  Segregating space in this way has

-  the benefits that: Mmapped space can always be individually released

-  back to the system, which helps keep the system level memory demands

-  of a long-lived program low.  Also, mapped memory doesn't become

-  `locked' between other chunks, as can happen with normally allocated

-  chunks, which means that even trimming via malloc_trim would not

-  release them.  However, it has the disadvantage that the space

-  cannot be reclaimed, consolidated, and then used to service later

-  requests, as happens with normal chunks.  The advantages of mmap

-  nearly always outweigh disadvantages for "large" chunks, but the

-  value of "large" may vary across systems.  The default is an

-  empirically derived value that works well in most systems. You can

-  disable mmap by setting to MAX_SIZE_T.

-

-*/

-

-#ifndef WIN32

-#ifdef _WIN32

-#define WIN32 1

-#endif  /* _WIN32 */

-#endif  /* WIN32 */

-#ifdef WIN32

-#define WIN32_LEAN_AND_MEAN

-#include <windows.h>

-#define HAVE_MMAP 1

-#define HAVE_MORECORE 0

-#define LACKS_UNISTD_H

-#define LACKS_SYS_PARAM_H

-#define LACKS_SYS_MMAN_H

-#define LACKS_STRING_H

-#define LACKS_STRINGS_H

-#define LACKS_SYS_TYPES_H

-#define LACKS_ERRNO_H

-#define MALLOC_FAILURE_ACTION

-#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */

-#endif  /* WIN32 */

-

-#if defined(DARWIN) || defined(_DARWIN)

-/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */

-#ifndef HAVE_MORECORE

-#define HAVE_MORECORE 0

-#define HAVE_MMAP 1

-#endif  /* HAVE_MORECORE */

-#endif  /* DARWIN */

-

-#ifndef LACKS_SYS_TYPES_H

-#include <sys/types.h>  /* For size_t */

-#endif  /* LACKS_SYS_TYPES_H */

-

-/* The maximum possible size_t value has all bits set */

-#define MAX_SIZE_T           (~(size_t)0)

-

-#ifndef ONLY_MSPACES

-#define ONLY_MSPACES 0

-#endif  /* ONLY_MSPACES */

-#ifndef MSPACES

-#if ONLY_MSPACES

-#define MSPACES 1

-#else   /* ONLY_MSPACES */

-#define MSPACES 0

-#endif  /* ONLY_MSPACES */

-#endif  /* MSPACES */

-#ifndef MALLOC_ALIGNMENT

-#define MALLOC_ALIGNMENT ((size_t)8U)

-#endif  /* MALLOC_ALIGNMENT */

-#ifndef FOOTERS

-#define FOOTERS 0

-#endif  /* FOOTERS */

-#ifndef ABORT

-#define ABORT  abort()

-#endif  /* ABORT */

-#ifndef ABORT_ON_ASSERT_FAILURE

-#define ABORT_ON_ASSERT_FAILURE 1

-#endif  /* ABORT_ON_ASSERT_FAILURE */

-#ifndef PROCEED_ON_ERROR

-#define PROCEED_ON_ERROR 0

-#endif  /* PROCEED_ON_ERROR */

-#ifndef USE_LOCKS

-#define USE_LOCKS 0

-#endif  /* USE_LOCKS */

-#ifndef INSECURE

-#define INSECURE 0

-#endif  /* INSECURE */

-#ifndef HAVE_MMAP

-#define HAVE_MMAP 1

-#endif  /* HAVE_MMAP */

-#ifndef MMAP_CLEARS

-#define MMAP_CLEARS 1

-#endif  /* MMAP_CLEARS */

-#ifndef HAVE_MREMAP

-#ifdef linux

-#define HAVE_MREMAP 1

-#else   /* linux */

-#define HAVE_MREMAP 0

-#endif  /* linux */

-#endif  /* HAVE_MREMAP */

-#ifndef MALLOC_FAILURE_ACTION

-#define MALLOC_FAILURE_ACTION  errno = ENOMEM;

-#endif  /* MALLOC_FAILURE_ACTION */

-#ifndef HAVE_MORECORE

-#if ONLY_MSPACES

-#define HAVE_MORECORE 0

-#else   /* ONLY_MSPACES */

-#define HAVE_MORECORE 1

-#endif  /* ONLY_MSPACES */

-#endif  /* HAVE_MORECORE */

-#if !HAVE_MORECORE

-#define MORECORE_CONTIGUOUS 0

-#else   /* !HAVE_MORECORE */

-#ifndef MORECORE

-#define MORECORE sbrk

-#endif  /* MORECORE */

-#ifndef MORECORE_CONTIGUOUS

-#define MORECORE_CONTIGUOUS 1

-#endif  /* MORECORE_CONTIGUOUS */

-#endif  /* HAVE_MORECORE */

-#ifndef DEFAULT_GRANULARITY

-#if MORECORE_CONTIGUOUS

-#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */

-#else   /* MORECORE_CONTIGUOUS */

-#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)

-#endif  /* MORECORE_CONTIGUOUS */

-#endif  /* DEFAULT_GRANULARITY */

-#ifndef DEFAULT_TRIM_THRESHOLD

-#ifndef MORECORE_CANNOT_TRIM

-#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)

-#else   /* MORECORE_CANNOT_TRIM */

-#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T

-#endif  /* MORECORE_CANNOT_TRIM */

-#endif  /* DEFAULT_TRIM_THRESHOLD */

-#ifndef DEFAULT_MMAP_THRESHOLD

-#if HAVE_MMAP

-#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)

-#else   /* HAVE_MMAP */

-#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T

-#endif  /* HAVE_MMAP */

-#endif  /* DEFAULT_MMAP_THRESHOLD */

-#ifndef USE_BUILTIN_FFS

-#define USE_BUILTIN_FFS 0

-#endif  /* USE_BUILTIN_FFS */

-#ifndef USE_DEV_RANDOM

-#define USE_DEV_RANDOM 0

-#endif  /* USE_DEV_RANDOM */

-#ifndef NO_MALLINFO

-#define NO_MALLINFO 0

-#endif  /* NO_MALLINFO */

-#ifndef MALLINFO_FIELD_TYPE

-#define MALLINFO_FIELD_TYPE size_t

-#endif  /* MALLINFO_FIELD_TYPE */

-

-/*

-  mallopt tuning options.  SVID/XPG defines four standard parameter

-  numbers for mallopt, normally defined in malloc.h.  None of these

-  are used in this malloc, so setting them has no effect. But this

-  malloc does support the following options.

-*/

-

-#define M_TRIM_THRESHOLD     (-1)

-#define M_GRANULARITY        (-2)

-#define M_MMAP_THRESHOLD     (-3)

-

-/* ------------------------ Mallinfo declarations ------------------------ */

-

-#if !NO_MALLINFO

-/*

-  This version of malloc supports the standard SVID/XPG mallinfo

-  routine that returns a struct containing usage properties and

-  statistics. It should work on any system that has a

-  /usr/include/malloc.h defining struct mallinfo.  The main

-  declaration needed is the mallinfo struct that is returned (by-copy)

-  by mallinfo().  The malloinfo struct contains a bunch of fields that

-  are not even meaningful in this version of malloc.  These fields are

-  are instead filled by mallinfo() with other numbers that might be of

-  interest.

-

-  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a

-  /usr/include/malloc.h file that includes a declaration of struct

-  mallinfo.  If so, it is included; else a compliant version is

-  declared below.  These must be precisely the same for mallinfo() to

-  work.  The original SVID version of this struct, defined on most

-  systems with mallinfo, declares all fields as ints. But some others

-  define as unsigned long. If your system defines the fields using a

-  type of different width than listed here, you MUST #include your

-  system version and #define HAVE_USR_INCLUDE_MALLOC_H.

-*/

-

-/* #define HAVE_USR_INCLUDE_MALLOC_H */

-

-#ifdef HAVE_USR_INCLUDE_MALLOC_H

-#include "/usr/include/malloc.h"

-#else /* HAVE_USR_INCLUDE_MALLOC_H */

-

-struct mallinfo {

-  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */

-  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */

-  MALLINFO_FIELD_TYPE smblks;   /* always 0 */

-  MALLINFO_FIELD_TYPE hblks;    /* always 0 */

-  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */

-  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */

-  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */

-  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */

-  MALLINFO_FIELD_TYPE fordblks; /* total free space */

-  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */

-};

-

-#endif /* HAVE_USR_INCLUDE_MALLOC_H */

-#endif /* NO_MALLINFO */

-

-#ifdef __cplusplus

-extern "C" {

-#endif /* __cplusplus */

-

-#if !ONLY_MSPACES

-

-/* ------------------- Declarations of public routines ------------------- */

-

-#ifndef USE_DL_PREFIX

-#define dlcalloc               calloc

-#define dlfree                 free

-#define dlmalloc               malloc

-#define dlmemalign             memalign

-#define dlrealloc              realloc

-#define dlvalloc               valloc

-#define dlpvalloc              pvalloc

-#define dlmallinfo             mallinfo

-#define dlmallopt              mallopt

-#define dlmalloc_trim          malloc_trim

-#define dlmalloc_stats         malloc_stats

-#define dlmalloc_usable_size   malloc_usable_size

-#define dlmalloc_footprint     malloc_footprint

-#define dlmalloc_max_footprint malloc_max_footprint

-#define dlindependent_calloc   independent_calloc

-#define dlindependent_comalloc independent_comalloc

-#endif /* USE_DL_PREFIX */

-

-

-/*

-  malloc(size_t n)

-  Returns a pointer to a newly allocated chunk of at least n bytes, or

-  null if no space is available, in which case errno is set to ENOMEM

-  on ANSI C systems.

-

-  If n is zero, malloc returns a minimum-sized chunk. (The minimum

-  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit

-  systems.)  Note that size_t is an unsigned type, so calls with

-  arguments that would be negative if signed are interpreted as

-  requests for huge amounts of space, which will often fail. The

-  maximum supported value of n differs across systems, but is in all

-  cases less than the maximum representable value of a size_t.

-*/

-void* dlmalloc(size_t);

-

-/*

-  free(void* p)

-  Releases the chunk of memory pointed to by p, that had been previously

-  allocated using malloc or a related routine such as realloc.

-  It has no effect if p is null. If p was not malloced or already

-  freed, free(p) will by default cause the current program to abort.

-*/

-void  dlfree(void*);

-

-/*

-  calloc(size_t n_elements, size_t element_size);

-  Returns a pointer to n_elements * element_size bytes, with all locations

-  set to zero.

-*/

-void* dlcalloc(size_t, size_t);

-

-/*

-  realloc(void* p, size_t n)

-  Returns a pointer to a chunk of size n that contains the same data

-  as does chunk p up to the minimum of (n, p's size) bytes, or null

-  if no space is available.

-

-  The returned pointer may or may not be the same as p. The algorithm

-  prefers extending p in most cases when possible, otherwise it

-  employs the equivalent of a malloc-copy-free sequence.

-

-  If p is null, realloc is equivalent to malloc.

-

-  If space is not available, realloc returns null, errno is set (if on

-  ANSI) and p is NOT freed.

-

-  if n is for fewer bytes than already held by p, the newly unused

-  space is lopped off and freed if possible.  realloc with a size

-  argument of zero (re)allocates a minimum-sized chunk.

-

-  The old unix realloc convention of allowing the last-free'd chunk

-  to be used as an argument to realloc is not supported.

-*/

-

-void* dlrealloc(void*, size_t);

-

-/*

-  memalign(size_t alignment, size_t n);

-  Returns a pointer to a newly allocated chunk of n bytes, aligned

-  in accord with the alignment argument.

-

-  The alignment argument should be a power of two. If the argument is

-  not a power of two, the nearest greater power is used.

-  8-byte alignment is guaranteed by normal malloc calls, so don't

-  bother calling memalign with an argument of 8 or less.

-

-  Overreliance on memalign is a sure way to fragment space.

-*/

-void* dlmemalign(size_t, size_t);

-

-/*

-  valloc(size_t n);

-  Equivalent to memalign(pagesize, n), where pagesize is the page

-  size of the system. If the pagesize is unknown, 4096 is used.

-*/

-void* dlvalloc(size_t);

-

-/*

-  mallopt(int parameter_number, int parameter_value)

-  Sets tunable parameters The format is to provide a

-  (parameter-number, parameter-value) pair.  mallopt then sets the

-  corresponding parameter to the argument value if it can (i.e., so

-  long as the value is meaningful), and returns 1 if successful else

-  0.  SVID/XPG/ANSI defines four standard param numbers for mallopt,

-  normally defined in malloc.h.  None of these are use in this malloc,

-  so setting them has no effect. But this malloc also supports other

-  options in mallopt. See below for details.  Briefly, supported

-  parameters are as follows (listed defaults are for "typical"

-  configurations).

-

-  Symbol            param #  default    allowed param values

-  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (MAX_SIZE_T disables)

-  M_GRANULARITY        -2     page size   any power of 2 >= page size

-  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)

-*/

-int dlmallopt(int, int);

-

-/*

-  malloc_footprint();

-  Returns the number of bytes obtained from the system.  The total

-  number of bytes allocated by malloc, realloc etc., is less than this

-  value. Unlike mallinfo, this function returns only a precomputed

-  result, so can be called frequently to monitor memory consumption.

-  Even if locks are otherwise defined, this function does not use them,

-  so results might not be up to date.

-*/

-size_t dlmalloc_footprint(void);

-

-/*

-  malloc_max_footprint();

-  Returns the maximum number of bytes obtained from the system. This

-  value will be greater than current footprint if deallocated space

-  has been reclaimed by the system. The peak number of bytes allocated

-  by malloc, realloc etc., is less than this value. Unlike mallinfo,

-  this function returns only a precomputed result, so can be called

-  frequently to monitor memory consumption.  Even if locks are

-  otherwise defined, this function does not use them, so results might

-  not be up to date.

-*/

-size_t dlmalloc_max_footprint(void);

-

-#if !NO_MALLINFO

-/*

-  mallinfo()

-  Returns (by copy) a struct containing various summary statistics:

-

-  arena:     current total non-mmapped bytes allocated from system

-  ordblks:   the number of free chunks

-  smblks:    always zero.

-  hblks:     current number of mmapped regions

-  hblkhd:    total bytes held in mmapped regions

-  usmblks:   the maximum total allocated space. This will be greater

-                than current total if trimming has occurred.

-  fsmblks:   always zero

-  uordblks:  current total allocated space (normal or mmapped)

-  fordblks:  total free space

-  keepcost:  the maximum number of bytes that could ideally be released

-               back to system via malloc_trim. ("ideally" means that

-               it ignores page restrictions etc.)

-

-  Because these fields are ints, but internal bookkeeping may

-  be kept as longs, the reported values may wrap around zero and

-  thus be inaccurate.

-*/

-struct mallinfo dlmallinfo(void);

-#endif /* NO_MALLINFO */

-

-/*

-  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);

-

-  independent_calloc is similar to calloc, but instead of returning a

-  single cleared space, it returns an array of pointers to n_elements

-  independent elements that can hold contents of size elem_size, each

-  of which starts out cleared, and can be independently freed,

-  realloc'ed etc. The elements are guaranteed to be adjacently

-  allocated (this is not guaranteed to occur with multiple callocs or

-  mallocs), which may also improve cache locality in some

-  applications.

-

-  The "chunks" argument is optional (i.e., may be null, which is

-  probably the most typical usage). If it is null, the returned array

-  is itself dynamically allocated and should also be freed when it is

-  no longer needed. Otherwise, the chunks array must be of at least

-  n_elements in length. It is filled in with the pointers to the

-  chunks.

-

-  In either case, independent_calloc returns this pointer array, or

-  null if the allocation failed.  If n_elements is zero and "chunks"

-  is null, it returns a chunk representing an array with zero elements

-  (which should be freed if not wanted).

-

-  Each element must be individually freed when it is no longer

-  needed. If you'd like to instead be able to free all at once, you

-  should instead use regular calloc and assign pointers into this

-  space to represent elements.  (In this case though, you cannot

-  independently free elements.)

-

-  independent_calloc simplifies and speeds up implementations of many

-  kinds of pools.  It may also be useful when constructing large data

-  structures that initially have a fixed number of fixed-sized nodes,

-  but the number is not known at compile time, and some of the nodes

-  may later need to be freed. For example:

-

-  struct Node { int item; struct Node* next; };

-

-  struct Node* build_list() {

-    struct Node** pool;

-    int n = read_number_of_nodes_needed();

-    if (n <= 0) return 0;

-    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);

-    if (pool == 0) die();

-    // organize into a linked list...

-    struct Node* first = pool[0];

-    for (i = 0; i < n-1; ++i)

-      pool[i]->next = pool[i+1];

-    free(pool);     // Can now free the array (or not, if it is needed later)

-    return first;

-  }

-*/

-void** dlindependent_calloc(size_t, size_t, void**);

-

-/*

-  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);

-

-  independent_comalloc allocates, all at once, a set of n_elements

-  chunks with sizes indicated in the "sizes" array.    It returns

-  an array of pointers to these elements, each of which can be

-  independently freed, realloc'ed etc. The elements are guaranteed to

-  be adjacently allocated (this is not guaranteed to occur with

-  multiple callocs or mallocs), which may also improve cache locality

-  in some applications.

-

-  The "chunks" argument is optional (i.e., may be null). If it is null

-  the returned array is itself dynamically allocated and should also

-  be freed when it is no longer needed. Otherwise, the chunks array

-  must be of at least n_elements in length. It is filled in with the

-  pointers to the chunks.

-

-  In either case, independent_comalloc returns this pointer array, or

-  null if the allocation failed.  If n_elements is zero and chunks is

-  null, it returns a chunk representing an array with zero elements

-  (which should be freed if not wanted).

-

-  Each element must be individually freed when it is no longer

-  needed. If you'd like to instead be able to free all at once, you

-  should instead use a single regular malloc, and assign pointers at

-  particular offsets in the aggregate space. (In this case though, you

-  cannot independently free elements.)

-

-  independent_comallac differs from independent_calloc in that each

-  element may have a different size, and also that it does not

-  automatically clear elements.

-

-  independent_comalloc can be used to speed up allocation in cases

-  where several structs or objects must always be allocated at the

-  same time.  For example:

-

-  struct Head { ... }

-  struct Foot { ... }

-

-  void send_message(char* msg) {

-    int msglen = strlen(msg);

-    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };

-    void* chunks[3];

-    if (independent_comalloc(3, sizes, chunks) == 0)

-      die();

-    struct Head* head = (struct Head*)(chunks[0]);

-    char*        body = (char*)(chunks[1]);

-    struct Foot* foot = (struct Foot*)(chunks[2]);

-    // ...

-  }

-

-  In general though, independent_comalloc is worth using only for

-  larger values of n_elements. For small values, you probably won't

-  detect enough difference from series of malloc calls to bother.

-

-  Overuse of independent_comalloc can increase overall memory usage,

-  since it cannot reuse existing noncontiguous small chunks that

-  might be available for some of the elements.

-*/

-void** dlindependent_comalloc(size_t, size_t*, void**);

-

-

-/*

-  pvalloc(size_t n);

-  Equivalent to valloc(minimum-page-that-holds(n)), that is,

-  round up n to nearest pagesize.

- */

-void*  dlpvalloc(size_t);

-

-/*

-  malloc_trim(size_t pad);

-

-  If possible, gives memory back to the system (via negative arguments

-  to sbrk) if there is unused memory at the `high' end of the malloc

-  pool or in unused MMAP segments. You can call this after freeing

-  large blocks of memory to potentially reduce the system-level memory

-  requirements of a program. However, it cannot guarantee to reduce

-  memory. Under some allocation patterns, some large free blocks of

-  memory will be locked between two used chunks, so they cannot be

-  given back to the system.

-

-  The `pad' argument to malloc_trim represents the amount of free

-  trailing space to leave untrimmed. If this argument is zero, only

-  the minimum amount of memory to maintain internal data structures

-  will be left. Non-zero arguments can be supplied to maintain enough

-  trailing space to service future expected allocations without having

-  to re-obtain memory from the system.

-

-  Malloc_trim returns 1 if it actually released any memory, else 0.

-*/

-int  dlmalloc_trim(size_t);

-

-/*

-  malloc_usable_size(void* p);

-

-  Returns the number of bytes you can actually use in

-  an allocated chunk, which may be more than you requested (although

-  often not) due to alignment and minimum size constraints.

-  You can use this many bytes without worrying about

-  overwriting other allocated objects. This is not a particularly great

-  programming practice. malloc_usable_size can be more useful in

-  debugging and assertions, for example:

-

-  p = malloc(n);

-  assert(malloc_usable_size(p) >= 256);

-*/

-size_t dlmalloc_usable_size(void*);

-

-/*

-  malloc_stats();

-  Prints on stderr the amount of space obtained from the system (both

-  via sbrk and mmap), the maximum amount (which may be more than

-  current if malloc_trim and/or munmap got called), and the current

-  number of bytes allocated via malloc (or realloc, etc) but not yet

-  freed. Note that this is the number of bytes allocated, not the

-  number requested. It will be larger than the number requested

-  because of alignment and bookkeeping overhead. Because it includes

-  alignment wastage as being in use, this figure may be greater than

-  zero even when no user-level chunks are allocated.

-

-  The reported current and maximum system memory can be inaccurate if

-  a program makes other calls to system memory allocation functions

-  (normally sbrk) outside of malloc.

-

-  malloc_stats prints only the most commonly interesting statistics.

-  More information can be obtained by calling mallinfo.

-*/

-void  dlmalloc_stats(void);

-

-#endif /* ONLY_MSPACES */

-

-#if MSPACES

-

-/*

-  mspace is an opaque type representing an independent

-  region of space that supports mspace_malloc, etc.

-*/

-typedef void* mspace;

-

-/*

-  create_mspace creates and returns a new independent space with the

-  given initial capacity, or, if 0, the default granularity size.  It

-  returns null if there is no system memory available to create the

-  space.  If argument locked is non-zero, the space uses a separate

-  lock to control access. The capacity of the space will grow

-  dynamically as needed to service mspace_malloc requests.  You can

-  control the sizes of incremental increases of this space by

-  compiling with a different DEFAULT_GRANULARITY or dynamically

-  setting with mallopt(M_GRANULARITY, value).

-*/

-mspace create_mspace(size_t capacity, int locked);

-

-/*

-  destroy_mspace destroys the given space, and attempts to return all

-  of its memory back to the system, returning the total number of

-  bytes freed. After destruction, the results of access to all memory

-  used by the space become undefined.

-*/

-size_t destroy_mspace(mspace msp);

-

-/*

-  create_mspace_with_base uses the memory supplied as the initial base

-  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this

-  space is used for bookkeeping, so the capacity must be at least this

-  large. (Otherwise 0 is returned.) When this initial space is

-  exhausted, additional memory will be obtained from the system.

-  Destroying this space will deallocate all additionally allocated

-  space (if possible) but not the initial base.

-*/

-mspace create_mspace_with_base(void* base, size_t capacity, int locked);

-

-/*

-  mspace_malloc behaves as malloc, but operates within

-  the given space.

-*/

-void* mspace_malloc(mspace msp, size_t bytes);

-

-/*

-  mspace_free behaves as free, but operates within

-  the given space.

-

-  If compiled with FOOTERS==1, mspace_free is not actually needed.

-  free may be called instead of mspace_free because freed chunks from

-  any space are handled by their originating spaces.

-*/

-void mspace_free(mspace msp, void* mem);

-

-/*

-  mspace_realloc behaves as realloc, but operates within

-  the given space.

-

-  If compiled with FOOTERS==1, mspace_realloc is not actually

-  needed.  realloc may be called instead of mspace_realloc because

-  realloced chunks from any space are handled by their originating

-  spaces.

-*/

-void* mspace_realloc(mspace msp, void* mem, size_t newsize);

-

-/*

-  mspace_calloc behaves as calloc, but operates within

-  the given space.

-*/

-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);

-

-/*

-  mspace_memalign behaves as memalign, but operates within

-  the given space.

-*/

-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);

-

-/*

-  mspace_independent_calloc behaves as independent_calloc, but

-  operates within the given space.

-*/

-void** mspace_independent_calloc(mspace msp, size_t n_elements,

-                                 size_t elem_size, void* chunks[]);

-

-/*

-  mspace_independent_comalloc behaves as independent_comalloc, but

-  operates within the given space.

-*/

-void** mspace_independent_comalloc(mspace msp, size_t n_elements,

-                                   size_t sizes[], void* chunks[]);

-

-/*

-  mspace_footprint() returns the number of bytes obtained from the

-  system for this space.

-*/

-size_t mspace_footprint(mspace msp);

-

-/*

-  mspace_max_footprint() returns the peak number of bytes obtained from the

-  system for this space.

-*/

-size_t mspace_max_footprint(mspace msp);

-

-

-#if !NO_MALLINFO

-/*

-  mspace_mallinfo behaves as mallinfo, but reports properties of

-  the given space.

-*/

-struct mallinfo mspace_mallinfo(mspace msp);

-#endif /* NO_MALLINFO */

-

-/*

-  mspace_malloc_stats behaves as malloc_stats, but reports

-  properties of the given space.

-*/

-void mspace_malloc_stats(mspace msp);

-

-/*

-  mspace_trim behaves as malloc_trim, but

-  operates within the given space.

-*/

-int mspace_trim(mspace msp, size_t pad);

-

-/*

-  An alias for mallopt.

-*/

-int mspace_mallopt(int, int);

-

-#endif /* MSPACES */

-

-#ifdef __cplusplus

-};  /* end of extern "C" */

-#endif /* __cplusplus */

-

-#endif /* DLMALLOC_H */

diff --git a/lib/generics.nim b/lib/generics.nim
deleted file mode 100644
index 1ed7651e1..000000000
--- a/lib/generics.nim
+++ /dev/null
@@ -1,169 +0,0 @@
-#
-#
-#            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-## This module contains basic abstract data types.
-
-type
-  TListItem[T] = object
-    next, prev: ref TListItem[T]
-    data: T
-
-  TList*[T] = ref TListItem[T]
-#  TIndex*[T] = object
-
-#proc succ*[T](i: TIndex[T]): TIndex[T] =
-#  result = i.next
-
-#proc pred*[T](i: TIndex[T]): TIndex[T] =
-#  result = i.prev
-
-#proc getIndex*[T](c: TList[T]): TIndex[TList[T]] =
-#  return c
-
-proc init*[T](c: var TList[T]) {.inline.} =
-  c = nil
-
-iterator items*[T](c: TList[T]): var T {.inline.} =
-  var it = c
-  while it != nil:
-    yield it.data
-    it = it.next
-
-proc add*[T](c: var TList[T], item: T) {.inline.} =
-  var it: ref TListItem[T]
-  new(it)
-  it.data = item
-  it.prev = c.prev
-  it.next = c.next
-  c = it
-
-proc incl*[T](c: var TList[T], item: T) =
-  for i in items(c):
-    if i == item: return
-  add(c, item)
-
-proc excl*[T](c: var TList[T], item: T) =
-  var it: TList[T] = c
-  while it != nil:
-    if it.data == item:
-      # remove from list
-    it = it.next
-
-proc del*[T](c: var TList[T], item: T) {.inline.} = excl(c, item)
-
-proc hash*(p: pointer): int {.inline.} =
-  # Returns the hash value of a pointer. This is very fast.
-  return cast[TAddress](p) shr 3
-
-proc hash*(x: int): int {.inline.} = return x
-proc hash*(x: char): int {.inline.} = return ord(x)
-proc hash*(x: bool): int {.inline.} = return ord(x)
-
-proc hash*(s: string): int =
-  # The generic hash table implementation work on a type `T` that has a hash
-  # proc. Predefined for string, pointers, int, char, bool.
-  var h = 0
-  for i in 0..s.len-1:
-    h = h +% Ord(s[i])
-    h = h +% h shl 10
-    h = h xor (h shr 6)
-  h = h +% h shl 3
-  h = h xor (h shr 11)
-  h = h +% h shl 15
-  result = h
-
-proc isNil*(x: int): bool {.inline.} = return x == low(int)
-proc nilValue*(x: int): int {.inline.} = return low(int)
-proc nilValue*(x: pointer): pointer {.inline.} = return nil
-proc nilValue*(x: string): string {.inline.} = return nil
-proc nilValue*[T](x: seq[T]): seq[T] {.inline.} = return nil
-proc nilValue*(x: float): float {.inline.} = return NaN
-
-proc mustRehash(len, counter: int): bool =
-  assert(len > counter)
-  result = (len * 2 < counter * 3) or (len-counter < 4)
-
-proc nextTry(h, maxHash: int): int {.inline.} =
-  return ((5*%h) +% 1) and maxHash
-
-type
-  TPair*[TKey, TValue] = tuple[key: TKey, val: TValue]
-  TTable*[TKey, TValue] =
-      object of TObject ## A table which stores (key, value)
-                        ## pairs. The used algorithm is hashing.
-    d: seq[TPair[TKey, TValue]]
-    counter: natural
-
-const
-  growthFactor = 2 # must be power of two
-
-proc init*[TKey, TValue](t: var TTable[TKey, TValue], capacity: natural = 32) =
-  newSeq(t.d, capacity)
-
-proc len*[TKey, TValue](t: TTable[TKey, TValue]): natural = return t.counter
-
-iterator pairs*[TKey,TValue](t: TTable[TKey,TValue]): TPair[TKey, TValue] =
-  for i in 0..t.d.len-1:
-    if not isNil(t.d[i].key):
-      yield (t.d[i].key, t.d[i].val)
-
-proc TableRawGet[TKey, TValue](t: TTable[TKey, TValue], key: TKey): int =
-  var h = hash(key) and high(t.d)
-  while not isNil(t.d[h].key):
-    if t.d[h].key == key: return h
-    h = nextTry(h, high(t.d))
-  return -1
-
-proc `[]`*[TKey, TValue](t: TTable[TKey, TValue], key: TKey): TValue =
-  var index = TableRawGet(t, key)
-  return if index >= 0: t.d[index].val else: nilValue(t.d[0].val)
-
-proc TableRawInsert[TKey, TValue](data: var seq[TPair[TKey, TValue]],
-                                  key: TKey, val: TValue) =
-  var h = hash(key) and high(data)
-  while not isNil(data[h].key):
-    assert(data[h].key != key)
-    h = nextTry(h, high(data))
-  assert(isNil(data[h].key))
-  data[h].key = key
-  data[h].val = val
-
-proc TableEnlarge[TKey, TValue](t: var TTable[TKey, TValue]) =
-  var n: seq[TPair[TKey,TValue]]
-  newSeq(n, len(t.d) * growthFactor)
-  for i in 0..high(t.d):
-    if not isNil(t.d[i].key):
-      TableRawInsert(n, t.d[i].key, t.d[i].val)
-  swap(t.d, n)
-
-proc `[]=`*[TKey, TValue](t: var TTable[TKey, TValue], key: TKey, val: TValue) =
-  var index = TableRawGet(t, key)
-  if index >= 0:
-    t.d[index].val = val
-  else:
-    if mustRehash(len(t.d), t.counter): TableEnlarge(t)
-    TableRawInsert(t.d, key, val)
-    inc(t.counter)
-
-proc add*[TKey, TValue](t: var TTable[TKey, TValue], key: TKey, val: TValue) =
-  if mustRehash(len(t.d), t.counter): TableEnlarge(t)
-  TableRawInsert(t.d, key, val)
-  inc(t.counter)
-
-proc test =
-  var
-    t: TTable[string, int]
-  init(t)
-  t["key1"] = 1
-  t["key2"] = 2
-  t["key3"] = 3
-  for key, val in pairs(t):
-    echo(key & " = " & $val)
-
-test()
diff --git a/lib/i386.asm.in b/lib/i386.asm.in
deleted file mode 100644
index 483dc2d95..000000000
--- a/lib/i386.asm.in
+++ /dev/null
@@ -1,70 +0,0 @@
-; This contains the CPU-dependant variants of some routines.

-; (C) 2005 Andreas Rumpf

-; This code was inspired by the Freepascal compiler's sources

-; All routines here have the _cdecl calling convention because

-; that is the only convention any C compiler supports.

-

-\python{

-# as usual I use my own preprocessor :-)

-import os

-

-def c(name): 

-  if os.name == 'posix':

-    return name

-  else:

-    return "_" + name

-}

-

-segment code

-

-global \c{cpu_inc_locked}

-global \c{cpu_dec_locked}

-global \c{cpu_lock}

-global \c{cpu_unlock}

-

-\c{cpu_dec_locked}:  

-          push ebp 

-          mov ebp,esp 

-          mov eax,[ebp+8] ; first parameter to function 

-          lock dec dword [eax]

-          setz      al

-          mov esp,ebp 

-          pop ebp 

-          ret

-

-\c{cpu_inc_locked}:

-          push ebp 

-          mov ebp,esp 

-          mov eax,[ebp+8] ; first parameter to function 

-          lock inc dword [eax]

-          mov esp,ebp 

-          pop ebp 

-          ret

-

-; This code uses the highest bit of the RC to indicate that the RC is

-; locked (spinlock).

-\c{cpu_lock}

-          push ebp 

-          mov ebp, esp 

-          mov eax, [ebp+8]     ; first parameter to function 

-          mov edx, [eax]       ; load RC

-          or  edx, 0x80000000  ; set highest bit

-     spin:

-          xchg [eax], edx      ; atomic instruction!

-          pause                ; wait a few cycles

-          and edx, 0x80000000  ; mask highest bit

-          jnz spin

-          mov esp, ebp

-          pop ebp

-          ret

-

-\c{cpu_unlock}

-          push ebp            

-          mov ebp, esp 

-          mov eax, [ebp+8]     ; first parameter to function 

-          mov edx, [eax]       ; load RC

-          and edx, 0x7FFFFFFF  ; unset highest bit

-          xchg [eax], edx      ; atomic instruction!

-          mov esp, ebp

-          pop ebp

-          ret

diff --git a/lib/base/dialogs.nim b/lib/impure/dialogs.nim
index cf81a3d29..cf81a3d29 100644
--- a/lib/base/dialogs.nim
+++ b/lib/impure/dialogs.nim
diff --git a/lib/base/web.nim b/lib/impure/web.nim
index 83d1406af..83d1406af 100644
--- a/lib/base/web.nim
+++ b/lib/impure/web.nim
diff --git a/lib/base/zip/zipfiles.nim b/lib/impure/zipfiles.nim
index e48b0f08e..e48b0f08e 100644
--- a/lib/base/zip/zipfiles.nim
+++ b/lib/impure/zipfiles.nim
diff --git a/lib/int64s.nim b/lib/int64s.nim
deleted file mode 100644
index 7a3dbad77..000000000
--- a/lib/int64s.nim
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-#
-#            Nimrod's Runtime Library
-#        (c) Copyright 2006 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# 64 bit integers for platforms that don't have those
-
-type
-  IInt64 = tuple[lo, hi: int32]
-
-proc cmpI64(x, y: IInt64): int32 {.compilerproc.} =
-  result = x.hi -% y.hi
-  if result == 0: result = x.lo -% y.lo
-
-proc addI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result = x
-  result.lo = result.lo +% y.lo
-  result.hi = result.hi +% y.hi
-  if y.lo > 0 and result.lo < y.lo:
-    inc(result.hi)
-  elif y.lo < 0 and result.lo > y.lo:
-    dec(result.hi)
-
-proc subI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result = x
-  result.lo = result.lo -% y.lo
-  result.hi = result.hi -% y.hi
-  if y.lo > 0 and result.lo < y.lo:
-    inc(result.hi)
-  elif y.lo < 0 and result.lo > y.lo:
-    dec(result.hi)
-
-proc mulI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result.lo = x.lo *% y.lo
-  result.hi = y.hi *% y.hi
-  if y.lo > 0 and result.lo < y.lo:
-    inc(result.hi)
-  elif y.lo < 0 and result.lo > y.lo:
-    dec(result.hi)
-
-proc divI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  # XXX: to implement
-
-proc modI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  # XXX: to implement
-
-proc bitandI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result.hi = x.hi and y.hi
-  result.lo = x.lo and y.lo
-
-proc bitorI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result.hi = x.hi or y.hi
-  result.lo = x.lo or y.lo
-
-proc bitxorI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  result.hi = x.hi xor y.hi
-  result.lo = x.lo xor y.lo
-
-proc bitnotI64(x: IInt64): IInt64 {.compilerproc.} =
-  result.lo = not x.lo
-  result.hi = not x.hi
-
-proc shlI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  # XXX: to implement
-
-proc shrI64(x, y: IInt64): IInt64 {.compilerproc.} =
-  # XXX: to implement
diff --git a/lib/locks.nim b/lib/locks.nim
deleted file mode 100644
index 89d26dfca..000000000
--- a/lib/locks.nim
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-#
-#            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-# Simple platform dependant lock implementation
-
-type
-  TSimpleLock = pointer
-
-proc initLock(s: TSimpleLock)
-proc deinitLock(s: TSimpleLock)
-proc lock(s: TSimpleLock)
-proc unlock(s: TSimpleLock)
diff --git a/lib/posix/detect.nim b/lib/posix/detect.nim
deleted file mode 100644
index d92269707..000000000
--- a/lib/posix/detect.nim
+++ /dev/null
@@ -1,824 +0,0 @@
-# Posix detect program
-# (c) 2009 Andreas Rumpf
-
-# This program produces a C program that produces a Nimrod include file.
-# The Nimrod include file lists the values of each POSIX constant.
-# This is needed because POSIX is brain-dead: It only cares for C, any other
-# language is ignored. It would have been easier had they specified the
-# concrete values of the constants. Sigh.
-
-import os, strutils
-
-const
-  cc = "gcc -o $1 $1.c"
-
-  cfile = """
-/* Generated by detect.nim */
-
-#include <stdlib.h>
-#include <stdio.h>
-$1
-
-int main() {
-  FILE* f;
-  f = fopen("$3_$4_consts.nim", "w+");
-  fputs("# Generated by detect.nim\nconst\n", f);
-  $2
-  fclose(f);
-}
-"""
-
-type
-  TTypeKind = enum 
-    cint, cshort, clong, cstring, pointer
-
-var
-  hd = ""
-  tl = ""
-
-proc myExec(cmd: string): bool = 
-  return executeShellCommand(cmd) == 0
-
-proc header(s: string): bool = 
-  const testh = "testh"
-  var f: TFile
-  if openFile(f, appendFileExt(testh, "c"), fmWrite):
-    f.write("#include $1\n" % s)
-    f.write("int main() { return 0; }\n")
-    closeFile(f)
-    result = myExec(cc % testh)
-    removeFile(appendFileExt(testh, "c"))
-  if result:
-    addf(hd, "#include $1\n", s)
-    echo("Found: ", s)
-  else:
-    echo("Not found: ", s)
-
-proc main = 
-  const gen = "genconsts"
-  var f: TFile
-  if openFile(f, appendFileExt(gen, "c"), fmWrite): 
-    f.write(cfile % [hd, tl, system.hostOS, system.hostCPU])
-    closeFile(f)
-  if not myExec(cc % gen): quit(1)
-  if not myExec("./" & gen): quit(1)
-  removeFile(appendFileExt(gen, "c"))
-  echo("Success")
-
-proc v(name: string, typ: TTypeKind=cint) = 
-  var n = if name[0] == '_': copy(name, 1) else: name
-  var t = $typ
-  case typ
-  of pointer: 
-    addf(tl, 
-      "#ifdef $3\n  fprintf(f, \"  $1* = cast[$2](%p)\\n\", $3);\n#endif\n", 
-      n, t, name)
-  
-  of cstring:
-    addf(tl, 
-      "#ifdef $3\n  fprintf(f, \"  $1* = $2(\\\"%s\\\")\\n\", $3);\n#endif\n",
-      n, t, name)
-  of clong:
-    addf(tl, 
-      "#ifdef $3\n  fprintf(f, \"  $1* = $2(%ld)\\n\", $3);\n#endif\n", 
-      n, t, name)  
-  else:  
-    addf(tl, 
-      "#ifdef $3\n  fprintf(f, \"  $1* = $2(%d)\\n\", $3);\n#endif\n", 
-      n, t, name)
-
-if header("<aio.h>"):
-  v("AIO_ALLDONE")
-  v("AIO_CANCELED")
-  v("AIO_NOTCANCELED")
-  v("LIO_NOP")
-  v("LIO_NOWAIT")
-  v("LIO_READ")
-  v("LIO_WAIT")
-  v("LIO_WRITE")
-
-if header("<dlfcn.h>"):
-  v("RTLD_LAZY")
-  v("RTLD_NOW")

-  v("RTLD_GLOBAL")

-  v("RTLD_LOCAL")

-
-if header("<errno.h>"):

-  v("E2BIG")

-  v("EACCES")

-  v("EADDRINUSE")

-  v("EADDRNOTAVAIL")

-  v("EAFNOSUPPORT")

-  v("EAGAIN")

-  v("EALREADY")

-  v("EBADF")

-  v("EBADMSG")

-  v("EBUSY")

-  v("ECANCELED")

-  v("ECHILD")

-  v("ECONNABORTED")

-  v("ECONNREFUSED")

-  v("ECONNRESET")

-  v("EDEADLK")

-  v("EDESTADDRREQ")

-  v("EDOM")

-  v("EDQUOT")

-  v("EEXIST")

-  v("EFAULT")

-  v("EFBIG")

-  v("EHOSTUNREACH")

-  v("EIDRM")

-  v("EILSEQ")

-  v("EINPROGRESS")

-  v("EINTR")

-  v("EINVAL")

-  v("EIO")

-  v("EISCONN")

-  v("EISDIR")

-  v("ELOOP")

-  v("EMFILE")

-  v("EMLINK")

-  v("EMSGSIZE")

-  v("EMULTIHOP")

-  v("ENAMETOOLONG")

-  v("ENETDOWN")

-  v("ENETRESET")

-  v("ENETUNREACH")

-  v("ENFILE")

-  v("ENOBUFS")

-  v("ENODATA")

-  v("ENODEV")

-  v("ENOENT")

-  v("ENOEXEC")

-  v("ENOLCK")

-  v("ENOLINK")

-  v("ENOMEM")

-  v("ENOMSG")

-  v("ENOPROTOOPT")

-  v("ENOSPC")

-  v("ENOSR")

-  v("ENOSTR")

-  v("ENOSYS")

-  v("ENOTCONN")

-  v("ENOTDIR")

-  v("ENOTEMPTY")

-  v("ENOTSOCK")

-  v("ENOTSUP")

-  v("ENOTTY")

-  v("ENXIO")

-  v("EOPNOTSUPP")

-  v("EOVERFLOW")

-  v("EPERM")

-  v("EPIPE")

-  v("EPROTO")

-  v("EPROTONOSUPPORT")

-  v("EPROTOTYPE")

-  v("ERANGE")

-  v("EROFS")

-  v("ESPIPE")

-  v("ESRCH")

-  v("ESTALE")

-  v("ETIME")

-  v("ETIMEDOUT")

-  v("ETXTBSY")

-  v("EWOULDBLOCK")

-  v("EXDEV")

-  
-if header("<fcntl.h>"):
-  v("F_DUPFD")

-  v("F_GETFD")

-  v("F_SETFD")

-  v("F_GETFL")

-  v("F_SETFL")

-  v("F_GETLK")

-  v("F_SETLK")

-  v("F_SETLKW")

-  v("F_GETOWN")

-  v("F_SETOWN")

-  v("FD_CLOEXEC")

-  v("F_RDLCK")

-  v("F_UNLCK")

-  v("F_WRLCK")

-  v("O_CREAT")

-  v("O_EXCL")

-  v("O_NOCTTY")

-  v("O_TRUNC")

-  v("O_APPEND")

-  v("O_DSYNC")

-  v("O_NONBLOCK")

-  v("O_RSYNC")

-  v("O_SYNC")

-  v("O_ACCMODE")

-  v("O_RDONLY")

-  v("O_RDWR")

-  v("O_WRONLY")

-  v("POSIX_FADV_NORMAL")

-  v("POSIX_FADV_SEQUENTIAL")

-  v("POSIX_FADV_RANDOM")

-  v("POSIX_FADV_WILLNEED")

-  v("POSIX_FADV_DONTNEED")

-  v("POSIX_FADV_NOREUSE")

-
-if header("<fenv.h>"):

-  v("FE_DIVBYZERO")

-  v("FE_INEXACT")

-  v("FE_INVALID")

-  v("FE_OVERFLOW")

-  v("FE_UNDERFLOW")

-  v("FE_ALL_EXCEPT")

-  v("FE_DOWNWARD")

-  v("FE_TONEAREST")

-  v("FE_TOWARDZERO")

-  v("FE_UPWARD")

-  v("FE_DFL_ENV", pointer)

-
-if header("<fmtmsg.h>"):

-  v("MM_HARD")

-  v("MM_SOFT")

-  v("MM_FIRM")

-  v("MM_APPL")

-  v("MM_UTIL")

-  v("MM_OPSYS")

-  v("MM_RECOVER")

-  v("MM_NRECOV")

-  v("MM_HALT")

-  v("MM_ERROR")

-  v("MM_WARNING")

-  v("MM_INFO")

-  v("MM_NOSEV")

-  v("MM_PRINT")

-  v("MM_CONSOLE")

-  v("MM_OK")

-  v("MM_NOTOK")

-  v("MM_NOMSG")

-  v("MM_NOCON")

-
-if header("<fnmatch.h>"):

-  v("FNM_NOMATCH")

-  v("FNM_PATHNAME")

-  v("FNM_PERIOD")

-  v("FNM_NOESCAPE")

-  v("FNM_NOSYS")

-
-if header("<ftw.h>"):

-  v("FTW_F")

-  v("FTW_D")

-  v("FTW_DNR")

-  v("FTW_DP")

-  v("FTW_NS")

-  v("FTW_SL")

-  v("FTW_SLN")

-  v("FTW_PHYS")

-  v("FTW_MOUNT")

-  v("FTW_DEPTH")

-  v("FTW_CHDIR")

-
-if header("<glob.h>"):
-  v("GLOB_APPEND")

-  v("GLOB_DOOFFS")

-  v("GLOB_ERR")

-  v("GLOB_MARK")

-  v("GLOB_NOCHECK")

-  v("GLOB_NOESCAPE")

-  v("GLOB_NOSORT")

-  v("GLOB_ABORTED")

-  v("GLOB_NOMATCH")

-  v("GLOB_NOSPACE")

-  v("GLOB_NOSYS")

-

-if header("<langinfo.h>"):
-  v("CODESET")

-  v("D_T_FMT")

-  v("D_FMT")

-  v("T_FMT")

-  v("T_FMT_AMPM")

-  v("AM_STR")

-  v("PM_STR")

-  v("DAY_1")

-  v("DAY_2")

-  v("DAY_3")

-  v("DAY_4")

-  v("DAY_5")

-  v("DAY_6")

-  v("DAY_7")

-  v("ABDAY_1")

-  v("ABDAY_2")

-  v("ABDAY_3")

-  v("ABDAY_4")

-  v("ABDAY_5")

-  v("ABDAY_6")

-  v("ABDAY_7")

-  v("MON_1")

-  v("MON_2")

-  v("MON_3")

-  v("MON_4")

-  v("MON_5")

-  v("MON_6")

-  v("MON_7")

-  v("MON_8")

-  v("MON_9")

-  v("MON_10")

-  v("MON_11")

-  v("MON_12")

-  v("ABMON_1")

-  v("ABMON_2")

-  v("ABMON_3")

-  v("ABMON_4")

-  v("ABMON_5")

-  v("ABMON_6")

-  v("ABMON_7")

-  v("ABMON_8")

-  v("ABMON_9")

-  v("ABMON_10")

-  v("ABMON_11")

-  v("ABMON_12")

-  v("ERA")

-  v("ERA_D_FMT")

-  v("ERA_D_T_FMT")

-  v("ERA_T_FMT")

-  v("ALT_DIGITS")

-  v("RADIXCHAR")

-  v("THOUSEP")

-  v("YESEXPR")

-  v("NOEXPR")

-  v("CRNCYSTR")

-    
-if header("<locale.h>"):

-  v("LC_ALL") #{.importc, header: .}: cint

-  v("LC_COLLATE") #{.importc, header: "<locale.h>".}: cint

-  v("LC_CTYPE") #{.importc, header: "<locale.h>".}: cint

-  v("LC_MESSAGES") #{.importc, header: "<locale.h>".}: cint

-  v("LC_MONETARY") #{.importc, header: "<locale.h>".}: cint

-  v("LC_NUMERIC") #{.importc, header: "<locale.h>".}: cint

-  v("LC_TIME") #{.importc, header: "<locale.h>".}: cint

-
-if header("<pthread.h>"):

-  v("PTHREAD_BARRIER_SERIAL_THREAD")

-  v("PTHREAD_CANCEL_ASYNCHRONOUS") 

-  v("PTHREAD_CANCEL_ENABLE") 

-  v("PTHREAD_CANCEL_DEFERRED")

-  v("PTHREAD_CANCEL_DISABLE") 

-  #v("PTHREAD_CANCELED")

-  #v("PTHREAD_COND_INITIALIZER") 

-  v("PTHREAD_CREATE_DETACHED")

-  v("PTHREAD_CREATE_JOINABLE")

-  v("PTHREAD_EXPLICIT_SCHED")

-  v("PTHREAD_INHERIT_SCHED") 

-  v("PTHREAD_MUTEX_DEFAULT") 

-  v("PTHREAD_MUTEX_ERRORCHECK")

-  #v("PTHREAD_MUTEX_INITIALIZER") 

-  v("PTHREAD_MUTEX_NORMAL") 

-  v("PTHREAD_MUTEX_RECURSIVE") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_ONCE_INIT") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_PRIO_INHERIT") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_PRIO_NONE") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_PRIO_PROTECT") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_PROCESS_SHARED") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_PROCESS_PRIVATE") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_SCOPE_PROCESS") #{.importc, header: "<pthread.h>".}: cint

-  v("PTHREAD_SCOPE_SYSTEM") #{.importc, header: "<pthread.h>".}: cint

-
-if header("<unistd.h>"):

-  v("_POSIX_ASYNC_IO")

-  v("_POSIX_PRIO_IO")

-  v("_POSIX_SYNC_IO")

-  v("F_OK")

-  v("R_OK")

-  v("W_OK")

-  v("X_OK")

-

-  v("_CS_PATH")

-  v("_CS_POSIX_V6_ILP32_OFF32_CFLAGS") 

-  v("_CS_POSIX_V6_ILP32_OFF32_LDFLAGS") 

-  v("_CS_POSIX_V6_ILP32_OFF32_LIBS") 

-  v("_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS") 

-  v("_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS") 

-  v("_CS_POSIX_V6_ILP32_OFFBIG_LIBS") 

-  v("_CS_POSIX_V6_LP64_OFF64_CFLAGS") 

-  v("_CS_POSIX_V6_LP64_OFF64_LDFLAGS")

-  v("_CS_POSIX_V6_LP64_OFF64_LIBS") 

-  v("_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS") 

-  v("_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS") 

-  v("_CS_POSIX_V6_LPBIG_OFFBIG_LIBS") 

-  v("_CS_POSIX_V6_WIDTH_RESTRICTED_ENVS")
-
-  v("F_LOCK") 

-  v("F_TEST") #{.importc: "F_TEST", header: "<unistd.h>".}: cint

-  v("F_TLOCK") #{.importc: "F_TLOCK", header: "<unistd.h>".}: cint

-  v("F_ULOCK") #{.importc: "F_ULOCK", header: "<unistd.h>".}: cint

-  v("_PC_2_SYMLINKS") #{.importc: "_PC_2_SYMLINKS", header: "<unistd.h>".}: cint

-  v("_PC_ALLOC_SIZE_MIN") 

-  v("_PC_ASYNC_IO") #{.importc: "_PC_ASYNC_IO", header: "<unistd.h>".}: cint

-  v("_PC_CHOWN_RESTRICTED") 

-  v("_PC_FILESIZEBITS") #{.importc: "_PC_FILESIZEBITS", header: "<unistd.h>".}: cint

-  v("_PC_LINK_MAX") #{.importc: "_PC_LINK_MAX", header: "<unistd.h>".}: cint

-  v("_PC_MAX_CANON") #{.importc: "_PC_MAX_CANON", header: "<unistd.h>".}: cint

-  v("_PC_MAX_INPUT") #{.importc: "_PC_MAX_INPUT", header: "<unistd.h>".}: cint

-  v("_PC_NAME_MAX") #{.importc: "_PC_NAME_MAX", header: "<unistd.h>".}: cint

-  v("_PC_NO_TRUNC") #{.importc: "_PC_NO_TRUNC", header: "<unistd.h>".}: cint

-  v("_PC_PATH_MAX") #{.importc: "_PC_PATH_MAX", header: "<unistd.h>".}: cint

-  v("_PC_PIPE_BUF") #{.importc: "_PC_PIPE_BUF", header: "<unistd.h>".}: cint

-  v("_PC_PRIO_IO") #{.importc: "_PC_PRIO_IO", header: "<unistd.h>".}: cint

-  v("_PC_REC_INCR_XFER_SIZE") 

-  v("_PC_REC_MIN_XFER_SIZE") 

-  v("_PC_REC_XFER_ALIGN") 

-  v("_PC_SYMLINK_MAX") #{.importc: "_PC_SYMLINK_MAX", header: "<unistd.h>".}: cint

-  v("_PC_SYNC_IO") #{.importc: "_PC_SYNC_IO", header: "<unistd.h>".}: cint

-  v("_PC_VDISABLE") #{.importc: "_PC_VDISABLE", header: "<unistd.h>".}: cint

-  v("_SC_2_C_BIND") #{.importc: "_SC_2_C_BIND", header: "<unistd.h>".}: cint

-  v("_SC_2_C_DEV") #{.importc: "_SC_2_C_DEV", header: "<unistd.h>".}: cint

-  v("_SC_2_CHAR_TERM") #{.importc: "_SC_2_CHAR_TERM", header: "<unistd.h>".}: cint

-  v("_SC_2_FORT_DEV") #{.importc: "_SC_2_FORT_DEV", header: "<unistd.h>".}: cint

-  v("_SC_2_FORT_RUN") #{.importc: "_SC_2_FORT_RUN", header: "<unistd.h>".}: cint

-  v("_SC_2_LOCALEDEF") #{.importc: "_SC_2_LOCALEDEF", header: "<unistd.h>".}: cint

-  v("_SC_2_PBS") #{.importc: "_SC_2_PBS", header: "<unistd.h>".}: cint

-  v("_SC_2_PBS_ACCOUNTING") 

-  v("_SC_2_PBS_CHECKPOINT") 

-  v("_SC_2_PBS_LOCATE") #{.importc: "_SC_2_PBS_LOCATE", header: "<unistd.h>".}: cint

-  v("_SC_2_PBS_MESSAGE") #{.importc: "_SC_2_PBS_MESSAGE", header: "<unistd.h>".}: cint

-  v("_SC_2_PBS_TRACK") #{.importc: "_SC_2_PBS_TRACK", header: "<unistd.h>".}: cint

-  v("_SC_2_SW_DEV") #{.importc: "_SC_2_SW_DEV", header: "<unistd.h>".}: cint

-  v("_SC_2_UPE") #{.importc: "_SC_2_UPE", header: "<unistd.h>".}: cint

-  v("_SC_2_VERSION") #{.importc: "_SC_2_VERSION", header: "<unistd.h>".}: cint

-  v("_SC_ADVISORY_INFO") #{.importc: "_SC_ADVISORY_INFO", header: "<unistd.h>".}: cint

-  v("_SC_AIO_LISTIO_MAX") 

-  v("_SC_AIO_MAX") #{.importc: "_SC_AIO_MAX", header: "<unistd.h>".}: cint

-  v("_SC_AIO_PRIO_DELTA_MAX") 

-  v("_SC_ARG_MAX") #{.importc: "_SC_ARG_MAX", header: "<unistd.h>".}: cint

-  v("_SC_ASYNCHRONOUS_IO") 

-  v("_SC_ATEXIT_MAX") #{.importc: "_SC_ATEXIT_MAX", header: "<unistd.h>".}: cint

-  v("_SC_BARRIERS") #{.importc: "_SC_BARRIERS", header: "<unistd.h>".}: cint

-  v("_SC_BC_BASE_MAX") #{.importc: "_SC_BC_BASE_MAX", header: "<unistd.h>".}: cint

-  v("_SC_BC_DIM_MAX") #{.importc: "_SC_BC_DIM_MAX", header: "<unistd.h>".}: cint

-  v("_SC_BC_SCALE_MAX") #{.importc: "_SC_BC_SCALE_MAX", header: "<unistd.h>".}: cint

-  v("_SC_BC_STRING_MAX") #{.importc: "_SC_BC_STRING_MAX", header: "<unistd.h>".}: cint

-  v("_SC_CHILD_MAX") #{.importc: "_SC_CHILD_MAX", header: "<unistd.h>".}: cint

-  v("_SC_CLK_TCK") #{.importc: "_SC_CLK_TCK", header: "<unistd.h>".}: cint

-  v("_SC_CLOCK_SELECTION") 

-  v("_SC_COLL_WEIGHTS_MAX")

-  v("_SC_CPUTIME") #{.importc: "_SC_CPUTIME", header: "<unistd.h>".}: cint

-  v("_SC_DELAYTIMER_MAX") 

-  v("_SC_EXPR_NEST_MAX") #{.importc: "_SC_EXPR_NEST_MAX", header: "<unistd.h>".}: cint

-  v("_SC_FSYNC") #{.importc: "_SC_FSYNC", header: "<unistd.h>".}: cint

-  v("_SC_GETGR_R_SIZE_MAX")

-  v("_SC_GETPW_R_SIZE_MAX")

-  v("_SC_HOST_NAME_MAX") #{.importc: "_SC_HOST_NAME_MAX", header: "<unistd.h>".}: cint

-  v("_SC_IOV_MAX") #{.importc: "_SC_IOV_MAX", header: "<unistd.h>".}: cint

-  v("_SC_IPV6") #{.importc: "_SC_IPV6", header: "<unistd.h>".}: cint

-  v("_SC_JOB_CONTROL") #{.importc: "_SC_JOB_CONTROL", header: "<unistd.h>".}: cint

-  v("_SC_LINE_MAX") #{.importc: "_SC_LINE_MAX", header: "<unistd.h>".}: cint

-  v("_SC_LOGIN_NAME_MAX") 

-  v("_SC_MAPPED_FILES") #{.importc: "_SC_MAPPED_FILES", header: "<unistd.h>".}: cint

-  v("_SC_MEMLOCK") #{.importc: "_SC_MEMLOCK", header: "<unistd.h>".}: cint

-  v("_SC_MEMLOCK_RANGE") #{.importc: "_SC_MEMLOCK_RANGE", header: "<unistd.h>".}: cint

-  v("_SC_MEMORY_PROTECTION")

-  v("_SC_MESSAGE_PASSING") 

-  v("_SC_MONOTONIC_CLOCK") 

-  v("_SC_MQ_OPEN_MAX") #{.importc: "_SC_MQ_OPEN_MAX", header: "<unistd.h>".}: cint

-  v("_SC_MQ_PRIO_MAX") #{.importc: "_SC_MQ_PRIO_MAX", header: "<unistd.h>".}: cint

-  v("_SC_NGROUPS_MAX") #{.importc: "_SC_NGROUPS_MAX", header: "<unistd.h>".}: cint

-  v("_SC_OPEN_MAX") #{.importc: "_SC_OPEN_MAX", header: "<unistd.h>".}: cint

-  v("_SC_PAGE_SIZE") #{.importc: "_SC_PAGE_SIZE", header: "<unistd.h>".}: cint

-  v("_SC_PRIORITIZED_IO") 

-  v("_SC_PRIORITY_SCHEDULING") 

-  v("_SC_RAW_SOCKETS") #{.importc: "_SC_RAW_SOCKETS", header: "<unistd.h>".}: cint

-  v("_SC_RE_DUP_MAX") #{.importc: "_SC_RE_DUP_MAX", header: "<unistd.h>".}: cint

-  v("_SC_READER_WRITER_LOCKS") 

-  v("_SC_REALTIME_SIGNALS") 

-  v("_SC_REGEXP") #{.importc: "_SC_REGEXP", header: "<unistd.h>".}: cint

-  v("_SC_RTSIG_MAX") #{.importc: "_SC_RTSIG_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SAVED_IDS") #{.importc: "_SC_SAVED_IDS", header: "<unistd.h>".}: cint

-  v("_SC_SEM_NSEMS_MAX") #{.importc: "_SC_SEM_NSEMS_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SEM_VALUE_MAX") #{.importc: "_SC_SEM_VALUE_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SEMAPHORES") #{.importc: "_SC_SEMAPHORES", header: "<unistd.h>".}: cint

-  v("_SC_SHARED_MEMORY_OBJECTS") 

-  v("_SC_SHELL") #{.importc: "_SC_SHELL", header: "<unistd.h>".}: cint

-  v("_SC_SIGQUEUE_MAX") #{.importc: "_SC_SIGQUEUE_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SPAWN") #{.importc: "_SC_SPAWN", header: "<unistd.h>".}: cint

-  v("_SC_SPIN_LOCKS") #{.importc: "_SC_SPIN_LOCKS", header: "<unistd.h>".}: cint

-  v("_SC_SPORADIC_SERVER") 

-  v("_SC_SS_REPL_MAX") #{.importc: "_SC_SS_REPL_MAX", header: "<unistd.h>".}: cint

-  v("_SC_STREAM_MAX") #{.importc: "_SC_STREAM_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SYMLOOP_MAX") #{.importc: "_SC_SYMLOOP_MAX", header: "<unistd.h>".}: cint

-  v("_SC_SYNCHRONIZED_IO") 

-  v("_SC_THREAD_ATTR_STACKADDR") 

-  v("_SC_THREAD_ATTR_STACKSIZE") 

-  v("_SC_THREAD_CPUTIME") 

-  v("_SC_THREAD_DESTRUCTOR_ITERATIONS") 

-  v("_SC_THREAD_KEYS_MAX") 

-  v("_SC_THREAD_PRIO_INHERIT") 

-  v("_SC_THREAD_PRIO_PROTECT") 

-  v("_SC_THREAD_PRIORITY_SCHEDULING") 

-  v("_SC_THREAD_PROCESS_SHARED") 

-  v("_SC_THREAD_SAFE_FUNCTIONS") 

-  v("_SC_THREAD_SPORADIC_SERVER")

-  v("_SC_THREAD_STACK_MIN") 

-  v("_SC_THREAD_THREADS_MAX") 

-  v("_SC_THREADS") #{.importc: "_SC_THREADS", header: "<unistd.h>".}: cint

-  v("_SC_TIMEOUTS") #{.importc: "_SC_TIMEOUTS", header: "<unistd.h>".}: cint

-  v("_SC_TIMER_MAX") #{.importc: "_SC_TIMER_MAX", header: "<unistd.h>".}: cint

-  v("_SC_TIMERS") #{.importc: "_SC_TIMERS", header: "<unistd.h>".}: cint

-  v("_SC_TRACE") #{.importc: "_SC_TRACE", header: "<unistd.h>".}: cint

-  v("_SC_TRACE_EVENT_FILTER") 

-  v("_SC_TRACE_EVENT_NAME_MAX")

-  v("_SC_TRACE_INHERIT") #{.importc: "_SC_TRACE_INHERIT", header: "<unistd.h>".}: cint

-  v("_SC_TRACE_LOG") #{.importc: "_SC_TRACE_LOG", header: "<unistd.h>".}: cint

-  v("_SC_TRACE_NAME_MAX") 

-  v("_SC_TRACE_SYS_MAX") #{.importc: "_SC_TRACE_SYS_MAX", header: "<unistd.h>".}: cint

-  v("_SC_TRACE_USER_EVENT_MAX") 

-  v("_SC_TTY_NAME_MAX") #{.importc: "_SC_TTY_NAME_MAX", header: "<unistd.h>".}: cint

-  v("_SC_TYPED_MEMORY_OBJECTS") 

-  v("_SC_TZNAME_MAX") #{.importc: "_SC_TZNAME_MAX", header: "<unistd.h>".}: cint

-  v("_SC_V6_ILP32_OFF32") 

-  v("_SC_V6_ILP32_OFFBIG") 

-  v("_SC_V6_LP64_OFF64") #{.importc: "_SC_V6_LP64_OFF64", header: "<unistd.h>".}: cint

-  v("_SC_V6_LPBIG_OFFBIG") 

-  v("_SC_VERSION") #{.importc: "_SC_VERSION", header: "<unistd.h>".}: cint

-  v("_SC_XBS5_ILP32_OFF32") 

-  v("_SC_XBS5_ILP32_OFFBIG") 

-  v("_SC_XBS5_LP64_OFF64") 

-  v("_SC_XBS5_LPBIG_OFFBIG") 

-  v("_SC_XOPEN_CRYPT") #{.importc: "_SC_XOPEN_CRYPT", header: "<unistd.h>".}: cint

-  v("_SC_XOPEN_ENH_I18N") 

-  v("_SC_XOPEN_LEGACY") #{.importc: "_SC_XOPEN_LEGACY", header: "<unistd.h>".}: cint

-  v("_SC_XOPEN_REALTIME") 

-  v("_SC_XOPEN_REALTIME_THREADS") 

-  v("_SC_XOPEN_SHM") #{.importc: "_SC_XOPEN_SHM", header: "<unistd.h>".}: cint

-  v("_SC_XOPEN_STREAMS") #{.importc: "_SC_XOPEN_STREAMS", header: "<unistd.h>".}: cint

-  v("_SC_XOPEN_UNIX") #{.importc: "_SC_XOPEN_UNIX", header: "<unistd.h>".}: cint

-  v("_SC_XOPEN_VERSION") #{.importc: "_SC_XOPEN_VERSION", header: "<unistd.h>".}: cint

-
-  v("SEEK_SET") #{.importc, header: "<unistd.h>".}: cint

-  v("SEEK_CUR") #{.importc, header: "<unistd.h>".}: cint

-  v("SEEK_END") #{.importc, header: "<unistd.h>".}: cint

-
-
-if header("<semaphore.h>"):

-  v("SEM_FAILED", pointer)
-
-if header("<sys/ipc.h>"):

-  v("IPC_CREAT") #{.importc, header: .}: cint

-  v("IPC_EXCL") #{.importc, header: "<sys/ipc.h>".}: cint

-  v("IPC_NOWAIT") #{.importc, header: "<sys/ipc.h>".}: cint

-  v("IPC_PRIVATE") #{.importc, header: "<sys/ipc.h>".}: cint

-  v("IPC_RMID") #{.importc, header: "<sys/ipc.h>".}: cint

-  v("IPC_SET") #{.importc, header: "<sys/ipc.h>".}: cint

-  v("IPC_STAT") #{.importc, header: "<sys/ipc.h>".}: cint
-
-if header("<sys/stat.h>"):

-  v("S_IFMT") #{.importc, header: .}: cint

-  v("S_IFBLK") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFCHR") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFIFO") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFREG") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFDIR") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFLNK") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IFSOCK") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IRWXU") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IRUSR") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IWUSR") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IXUSR") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IRWXG") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IRGRP") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IWGRP") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IXGRP") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IRWXO") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IROTH") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IWOTH") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_IXOTH") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_ISUID") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_ISGID") #{.importc, header: "<sys/stat.h>".}: cint

-  v("S_ISVTX") #{.importc, header: "<sys/stat.h>".}: cint

-
-if header("<sys/statvfs.h>"):

-  v("ST_RDONLY") #{.importc, header: .}: cint

-  v("ST_NOSUID") #{.importc, header: "<sys/statvfs.h>".}: cint

-       
-if header("<sys/mman.h>"):

-  v("PROT_READ") #{.importc, header: .}: cint

-  v("PROT_WRITE") #{.importc, header: "<sys/mman.h>".}: cint

-  v("PROT_EXEC") #{.importc, header: "<sys/mman.h>".}: cint

-  v("PROT_NONE") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MAP_SHARED") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MAP_PRIVATE") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MAP_FIXED") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MS_ASYNC") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MS_SYNC") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MS_INVALIDATE") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MCL_CURRENT") #{.importc, header: "<sys/mman.h>".}: cint

-  v("MCL_FUTURE") #{.importc, header: "<sys/mman.h>".}: cint

-
-  v("MAP_FAILED", pointer)

-  v("POSIX_MADV_NORMAL") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_MADV_SEQUENTIAL") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_MADV_RANDOM") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_MADV_WILLNEED") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_MADV_DONTNEED") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_TYPED_MEM_ALLOCATE") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_TYPED_MEM_ALLOCATE_CONTIG") #{.importc, header: "<sys/mman.h>".}: cint

-  v("POSIX_TYPED_MEM_MAP_ALLOCATABLE") #{.importc, header: "<sys/mman.h>".}: cint

-

-if header("<time.h>"):

-  v("CLOCKS_PER_SEC", clong) 

-  v("CLOCK_PROCESS_CPUTIME_ID")

-  v("CLOCK_THREAD_CPUTIME_ID")

-  v("CLOCK_REALTIME")

-  v("TIMER_ABSTIME") 

-  v("CLOCK_MONOTONIC") 

-
-if header("<sys/wait.h>"):

-  v("WNOHANG") #{.importc, header: .}: cint

-  v("WUNTRACED") #{.importc, header: "<sys/wait.h>".}: cint

-  #v("WEXITSTATUS") 

-  #v("WIFCONTINUED") 

-  #v("WIFEXITED") 

-  #v("WIFSIGNALED")

-  #v("WIFSTOPPED") 

-  #v("WSTOPSIG") 

-  #v("WTERMSIG") 

-  v("WEXITED") #{.importc, header: "<sys/wait.h>".}: cint

-  v("WSTOPPED") #{.importc, header: "<sys/wait.h>".}: cint

-  v("WCONTINUED") #{.importc, header: "<sys/wait.h>".}: cint

-  v("WNOWAIT") #{.importc, header: "<sys/wait.h>".}: cint

-  v("P_ALL") #{.importc, header: "<sys/wait.h>".}: cint 

-  v("P_PID") #{.importc, header: "<sys/wait.h>".}: cint 

-  v("P_PGID") #{.importc, header: "<sys/wait.h>".}: cint

-         
-if header("<signal.h>"):

-  v("SIGEV_NONE") #{.importc, header: "<signal.h>".}: cint

-  v("SIGEV_SIGNAL") #{.importc, header: "<signal.h>".}: cint

-  v("SIGEV_THREAD") #{.importc, header: "<signal.h>".}: cint

-  v("SIGABRT") #{.importc, header: "<signal.h>".}: cint

-  v("SIGALRM") #{.importc, header: "<signal.h>".}: cint

-  v("SIGBUS") #{.importc, header: "<signal.h>".}: cint

-  v("SIGCHLD") #{.importc, header: "<signal.h>".}: cint

-  v("SIGCONT") #{.importc, header: "<signal.h>".}: cint

-  v("SIGFPE") #{.importc, header: "<signal.h>".}: cint

-  v("SIGHUP") #{.importc, header: "<signal.h>".}: cint

-  v("SIGILL") #{.importc, header: "<signal.h>".}: cint

-  v("SIGINT") #{.importc, header: "<signal.h>".}: cint

-  v("SIGKILL") #{.importc, header: "<signal.h>".}: cint

-  v("SIGPIPE") #{.importc, header: "<signal.h>".}: cint

-  v("SIGQUIT") #{.importc, header: "<signal.h>".}: cint

-  v("SIGSEGV") #{.importc, header: "<signal.h>".}: cint

-  v("SIGSTOP") #{.importc, header: "<signal.h>".}: cint

-  v("SIGTERM") #{.importc, header: "<signal.h>".}: cint

-  v("SIGTSTP") #{.importc, header: "<signal.h>".}: cint

-  v("SIGTTIN") #{.importc, header: "<signal.h>".}: cint

-  v("SIGTTOU") #{.importc, header: "<signal.h>".}: cint

-  v("SIGUSR1") #{.importc, header: "<signal.h>".}: cint

-  v("SIGUSR2") #{.importc, header: "<signal.h>".}: cint

-  v("SIGPOLL") #{.importc, header: "<signal.h>".}: cint

-  v("SIGPROF") #{.importc, header: "<signal.h>".}: cint

-  v("SIGSYS") #{.importc, header: "<signal.h>".}: cint

-  v("SIGTRAP") #{.importc, header: "<signal.h>".}: cint

-  v("SIGURG") #{.importc, header: "<signal.h>".}: cint

-  v("SIGVTALRM") #{.importc, header: "<signal.h>".}: cint

-  v("SIGXCPU") #{.importc, header: "<signal.h>".}: cint

-  v("SIGXFSZ") #{.importc, header: "<signal.h>".}: cint

-  v("SA_NOCLDSTOP") #{.importc, header: "<signal.h>".}: cint

-  v("SIG_BLOCK") #{.importc, header: "<signal.h>".}: cint

-  v("SIG_UNBLOCK") #{.importc, header: "<signal.h>".}: cint

-  v("SIG_SETMASK") #{.importc, header: "<signal.h>".}: cint

-  v("SA_ONSTACK") #{.importc, header: "<signal.h>".}: cint

-  v("SA_RESETHAND") #{.importc, header: "<signal.h>".}: cint

-  v("SA_RESTART") #{.importc, header: "<signal.h>".}: cint

-  v("SA_SIGINFO") #{.importc, header: "<signal.h>".}: cint

-  v("SA_NOCLDWAIT") #{.importc, header: "<signal.h>".}: cint

-  v("SA_NODEFER") #{.importc, header: "<signal.h>".}: cint

-  v("SS_ONSTACK") #{.importc, header: "<signal.h>".}: cint

-  v("SS_DISABLE") #{.importc, header: "<signal.h>".}: cint

-  v("MINSIGSTKSZ") #{.importc, header: "<signal.h>".}: cint

-  v("SIGSTKSZ") #{.importc, header: "<signal.h>".}: cint

-
-if header("<nl_types.h>"):

-  v("NL_SETD") #{.importc, header: .}: cint

-  v("NL_CAT_LOCALE") #{.importc, header: "<nl_types.h>".}: cint

-
-if header("<sched.h>"):

-  v("SCHED_FIFO")

-  v("SCHED_RR")

-  v("SCHED_SPORADIC")

-  v("SCHED_OTHER")

-
-if header("<sys/select.h>"):
-  v("FD_SETSIZE")

-

-if header("<net/if.h>"):
-  v("IF_NAMESIZE")
-
-if header("<sys/socket.h>"):
-  v("SCM_RIGHTS") #{.importc, header: .}: cint
-  v("SOCK_DGRAM") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SOCK_RAW") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SOCK_SEQPACKET") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SOCK_STREAM") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SOL_SOCKET") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_ACCEPTCONN") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_BROADCAST") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_DEBUG") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_DONTROUTE") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_ERROR") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_KEEPALIVE") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_LINGER") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_OOBINLINE") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_RCVBUF") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_RCVLOWAT") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_RCVTIMEO") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_REUSEADDR") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_SNDBUF") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_SNDLOWAT") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_SNDTIMEO") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SO_TYPE") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SOMAXCONN") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_CTRUNC") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_DONTROUTE") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_EOR") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_OOB") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_PEEK") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_TRUNC") #{.importc, header: "<sys/socket.h>".}: cint
-  v("MSG_WAITALL") #{.importc, header: "<sys/socket.h>".}: cint
-  v("AF_INET") #{.importc, header: "<sys/socket.h>".}: cint
-  v("AF_INET6") #{.importc, header: "<sys/socket.h>".}: cint
-  v("AF_UNIX") #{.importc, header: "<sys/socket.h>".}: cint
-  v("AF_UNSPEC") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SHUT_RD") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SHUT_RDWR") #{.importc, header: "<sys/socket.h>".}: cint
-  v("SHUT_WR") #{.importc, header: "<sys/socket.h>".}: cint
-
-if header("<netinet/in.h>"):
-  v("IPPROTO_IP") #{.importc, header: .}: cint
-  v("IPPROTO_IPV6") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPPROTO_ICMP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPPROTO_RAW") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPPROTO_TCP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPPROTO_UDP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("INADDR_ANY") #{.importc, header: "<netinet/in.h>".}: TinAddrScalar
-  v("INADDR_BROADCAST") #{.importc, header: "<netinet/in.h>".}: TinAddrScalar
-  v("INET_ADDRSTRLEN") #{.importc, header: "<netinet/in.h>".}: cint
-
-  v("IPV6_JOIN_GROUP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_LEAVE_GROUP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_MULTICAST_HOPS") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_MULTICAST_IF") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_MULTICAST_LOOP") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_UNICAST_HOPS") #{.importc, header: "<netinet/in.h>".}: cint
-  v("IPV6_V6ONLY") #{.importc, header: "<netinet/in.h>".}: cint
-
-  v("TCP_NODELAY") #{.importc, header: "<netinet/tcp.h>".}: cint
-
-if header("<netdb.h>"):
-  v("IPPORT_RESERVED")
-
-  v("HOST_NOT_FOUND")
-  v("NO_DATA")
-  v("NO_RECOVERY") 
-  v("TRY_AGAIN") 
-
-  v("AI_PASSIVE") 
-  v("AI_CANONNAME") 
-  v("AI_NUMERICHOST") 
-  v("AI_NUMERICSERV") 
-  v("AI_V4MAPPED") 
-  v("AI_ALL") 
-  v("AI_ADDRCONFIG") 
-
-  v("NI_NOFQDN") 
-  v("NI_NUMERICHOST") 
-  v("NI_NAMEREQD") 
-  v("NI_NUMERICSERV") 
-  v("NI_NUMERICSCOPE") 
-  v("NI_DGRAM") 
-  v("EAI_AGAIN")
-  v("EAI_BADFLAGS")
-  v("EAI_FAIL")
-  v("EAI_FAMILY")
-  v("EAI_MEMORY")
-  v("EAI_NONAME")
-  v("EAI_SERVICE")
-  v("EAI_SOCKTYPE")
-  v("EAI_SYSTEM")
-  v("EAI_OVERFLOW")
-
-if header("<poll.h>"):
-  v("POLLIN", cshort)
-  v("POLLRDNORM", cshort)
-  v("POLLRDBAND", cshort)
-  v("POLLPRI", cshort)
-  v("POLLOUT", cshort)
-  v("POLLWRNORM", cshort)
-  v("POLLWRBAND", cshort)
-  v("POLLERR", cshort)
-  v("POLLHUP", cshort)
-  v("POLLNVAL", cshort)
-
-if header("<spawn.h>"):
-  v("POSIX_SPAWN_RESETIDS")

-  v("POSIX_SPAWN_SETPGROUP")

-  v("POSIX_SPAWN_SETSCHEDPARAM")

-  v("POSIX_SPAWN_SETSCHEDULER")

-  v("POSIX_SPAWN_SETSIGDEF")

-  v("POSIX_SPAWN_SETSIGMASK")

-
-main()
-
diff --git a/lib/posix/linux_amd64_consts.nim b/lib/posix/linux_amd64_consts.nim
deleted file mode 100644
index 2fadcd83b..000000000
--- a/lib/posix/linux_amd64_consts.nim
+++ /dev/null
@@ -1,620 +0,0 @@
-# Generated by detect.nim
-const
-  AIO_ALLDONE* = cint(2)
-  AIO_CANCELED* = cint(0)
-  AIO_NOTCANCELED* = cint(1)
-  LIO_NOP* = cint(2)
-  LIO_NOWAIT* = cint(1)
-  LIO_READ* = cint(0)
-  LIO_WAIT* = cint(0)
-  LIO_WRITE* = cint(1)
-  RTLD_LAZY* = cint(1)
-  RTLD_NOW* = cint(2)
-  RTLD_GLOBAL* = cint(256)
-  RTLD_LOCAL* = cint(0)
-  E2BIG* = cint(7)
-  EACCES* = cint(13)
-  EADDRINUSE* = cint(98)
-  EADDRNOTAVAIL* = cint(99)
-  EAFNOSUPPORT* = cint(97)
-  EAGAIN* = cint(11)
-  EALREADY* = cint(114)
-  EBADF* = cint(9)
-  EBADMSG* = cint(74)
-  EBUSY* = cint(16)
-  ECANCELED* = cint(125)
-  ECHILD* = cint(10)
-  ECONNABORTED* = cint(103)
-  ECONNREFUSED* = cint(111)
-  ECONNRESET* = cint(104)
-  EDEADLK* = cint(35)
-  EDESTADDRREQ* = cint(89)
-  EDOM* = cint(33)
-  EDQUOT* = cint(122)
-  EEXIST* = cint(17)
-  EFAULT* = cint(14)
-  EFBIG* = cint(27)
-  EHOSTUNREACH* = cint(113)
-  EIDRM* = cint(43)
-  EILSEQ* = cint(84)
-  EINPROGRESS* = cint(115)
-  EINTR* = cint(4)
-  EINVAL* = cint(22)
-  EIO* = cint(5)
-  EISCONN* = cint(106)
-  EISDIR* = cint(21)
-  ELOOP* = cint(40)
-  EMFILE* = cint(24)
-  EMLINK* = cint(31)
-  EMSGSIZE* = cint(90)
-  EMULTIHOP* = cint(72)
-  ENAMETOOLONG* = cint(36)
-  ENETDOWN* = cint(100)
-  ENETRESET* = cint(102)
-  ENETUNREACH* = cint(101)
-  ENFILE* = cint(23)
-  ENOBUFS* = cint(105)
-  ENODATA* = cint(61)
-  ENODEV* = cint(19)
-  ENOENT* = cint(2)
-  ENOEXEC* = cint(8)
-  ENOLCK* = cint(37)
-  ENOLINK* = cint(67)
-  ENOMEM* = cint(12)
-  ENOMSG* = cint(42)
-  ENOPROTOOPT* = cint(92)
-  ENOSPC* = cint(28)
-  ENOSR* = cint(63)
-  ENOSTR* = cint(60)
-  ENOSYS* = cint(38)
-  ENOTCONN* = cint(107)
-  ENOTDIR* = cint(20)
-  ENOTEMPTY* = cint(39)
-  ENOTSOCK* = cint(88)
-  ENOTSUP* = cint(95)
-  ENOTTY* = cint(25)
-  ENXIO* = cint(6)
-  EOPNOTSUPP* = cint(95)
-  EOVERFLOW* = cint(75)
-  EPERM* = cint(1)
-  EPIPE* = cint(32)
-  EPROTO* = cint(71)
-  EPROTONOSUPPORT* = cint(93)
-  EPROTOTYPE* = cint(91)
-  ERANGE* = cint(34)
-  EROFS* = cint(30)
-  ESPIPE* = cint(29)
-  ESRCH* = cint(3)
-  ESTALE* = cint(116)
-  ETIME* = cint(62)
-  ETIMEDOUT* = cint(110)
-  ETXTBSY* = cint(26)
-  EWOULDBLOCK* = cint(11)
-  EXDEV* = cint(18)
-  F_DUPFD* = cint(0)
-  F_GETFD* = cint(1)
-  F_SETFD* = cint(2)
-  F_GETFL* = cint(3)
-  F_SETFL* = cint(4)
-  F_GETLK* = cint(5)
-  F_SETLK* = cint(6)
-  F_SETLKW* = cint(7)
-  F_GETOWN* = cint(9)
-  F_SETOWN* = cint(8)
-  FD_CLOEXEC* = cint(1)
-  F_RDLCK* = cint(0)
-  F_UNLCK* = cint(2)
-  F_WRLCK* = cint(1)
-  O_CREAT* = cint(64)
-  O_EXCL* = cint(128)
-  O_NOCTTY* = cint(256)
-  O_TRUNC* = cint(512)
-  O_APPEND* = cint(1024)
-  O_DSYNC* = cint(4096)
-  O_NONBLOCK* = cint(2048)
-  O_RSYNC* = cint(4096)
-  O_SYNC* = cint(4096)
-  O_ACCMODE* = cint(3)
-  O_RDONLY* = cint(0)
-  O_RDWR* = cint(2)
-  O_WRONLY* = cint(1)
-  POSIX_FADV_NORMAL* = cint(0)
-  POSIX_FADV_SEQUENTIAL* = cint(2)
-  POSIX_FADV_RANDOM* = cint(1)
-  POSIX_FADV_WILLNEED* = cint(3)
-  POSIX_FADV_DONTNEED* = cint(4)
-  POSIX_FADV_NOREUSE* = cint(5)
-  FE_DIVBYZERO* = cint(4)
-  FE_INEXACT* = cint(32)
-  FE_INVALID* = cint(1)
-  FE_OVERFLOW* = cint(8)
-  FE_UNDERFLOW* = cint(16)
-  FE_ALL_EXCEPT* = cint(61)
-  FE_DOWNWARD* = cint(1024)
-  FE_TONEAREST* = cint(0)
-  FE_TOWARDZERO* = cint(3072)
-  FE_UPWARD* = cint(2048)
-  FE_DFL_ENV* = cast[pointer](0xffffffffffffffff)
-  MM_HARD* = cint(1)
-  MM_SOFT* = cint(2)
-  MM_FIRM* = cint(4)
-  MM_APPL* = cint(8)
-  MM_UTIL* = cint(16)
-  MM_OPSYS* = cint(32)
-  MM_RECOVER* = cint(64)
-  MM_NRECOV* = cint(128)
-  MM_HALT* = cint(1)
-  MM_ERROR* = cint(2)
-  MM_WARNING* = cint(3)
-  MM_INFO* = cint(4)
-  MM_NOSEV* = cint(0)
-  MM_PRINT* = cint(256)
-  MM_CONSOLE* = cint(512)
-  MM_OK* = cint(0)
-  MM_NOTOK* = cint(-1)
-  MM_NOMSG* = cint(1)
-  MM_NOCON* = cint(4)
-  FNM_NOMATCH* = cint(1)
-  FNM_PATHNAME* = cint(1)
-  FNM_PERIOD* = cint(4)
-  FNM_NOESCAPE* = cint(2)
-  FTW_F* = cint(0)
-  FTW_D* = cint(1)
-  FTW_DNR* = cint(2)
-  FTW_NS* = cint(3)
-  FTW_SL* = cint(4)
-  GLOB_APPEND* = cint(32)
-  GLOB_DOOFFS* = cint(8)
-  GLOB_ERR* = cint(1)
-  GLOB_MARK* = cint(2)
-  GLOB_NOCHECK* = cint(16)
-  GLOB_NOESCAPE* = cint(64)
-  GLOB_NOSORT* = cint(4)
-  GLOB_ABORTED* = cint(2)
-  GLOB_NOMATCH* = cint(3)
-  GLOB_NOSPACE* = cint(1)
-  GLOB_NOSYS* = cint(4)
-  CODESET* = cint(14)
-  D_T_FMT* = cint(131112)
-  D_FMT* = cint(131113)
-  T_FMT* = cint(131114)
-  T_FMT_AMPM* = cint(131115)
-  AM_STR* = cint(131110)
-  PM_STR* = cint(131111)
-  DAY_1* = cint(131079)
-  DAY_2* = cint(131080)
-  DAY_3* = cint(131081)
-  DAY_4* = cint(131082)
-  DAY_5* = cint(131083)
-  DAY_6* = cint(131084)
-  DAY_7* = cint(131085)
-  ABDAY_1* = cint(131072)
-  ABDAY_2* = cint(131073)
-  ABDAY_3* = cint(131074)
-  ABDAY_4* = cint(131075)
-  ABDAY_5* = cint(131076)
-  ABDAY_6* = cint(131077)
-  ABDAY_7* = cint(131078)
-  MON_1* = cint(131098)
-  MON_2* = cint(131099)
-  MON_3* = cint(131100)
-  MON_4* = cint(131101)
-  MON_5* = cint(131102)
-  MON_6* = cint(131103)
-  MON_7* = cint(131104)
-  MON_8* = cint(131105)
-  MON_9* = cint(131106)
-  MON_10* = cint(131107)
-  MON_11* = cint(131108)
-  MON_12* = cint(131109)
-  ABMON_1* = cint(131086)
-  ABMON_2* = cint(131087)
-  ABMON_3* = cint(131088)
-  ABMON_4* = cint(131089)
-  ABMON_5* = cint(131090)
-  ABMON_6* = cint(131091)
-  ABMON_7* = cint(131092)
-  ABMON_8* = cint(131093)
-  ABMON_9* = cint(131094)
-  ABMON_10* = cint(131095)
-  ABMON_11* = cint(131096)
-  ABMON_12* = cint(131097)
-  ERA* = cint(131116)
-  ERA_D_FMT* = cint(131118)
-  ERA_D_T_FMT* = cint(131120)
-  ERA_T_FMT* = cint(131121)
-  ALT_DIGITS* = cint(131119)
-  RADIXCHAR* = cint(65536)
-  THOUSEP* = cint(65537)
-  YESEXPR* = cint(327680)
-  NOEXPR* = cint(327681)
-  CRNCYSTR* = cint(262159)
-  LC_ALL* = cint(6)
-  LC_COLLATE* = cint(3)
-  LC_CTYPE* = cint(0)
-  LC_MESSAGES* = cint(5)
-  LC_MONETARY* = cint(4)
-  LC_NUMERIC* = cint(1)
-  LC_TIME* = cint(2)
-  PTHREAD_BARRIER_SERIAL_THREAD* = cint(-1)
-  PTHREAD_CANCEL_ASYNCHRONOUS* = cint(1)
-  PTHREAD_CANCEL_ENABLE* = cint(0)
-  PTHREAD_CANCEL_DEFERRED* = cint(0)
-  PTHREAD_CANCEL_DISABLE* = cint(1)
-  PTHREAD_CREATE_DETACHED* = cint(1)
-  PTHREAD_CREATE_JOINABLE* = cint(0)
-  PTHREAD_EXPLICIT_SCHED* = cint(1)
-  PTHREAD_INHERIT_SCHED* = cint(0)
-  PTHREAD_ONCE_INIT* = cint(0)
-  PTHREAD_PROCESS_SHARED* = cint(1)
-  PTHREAD_PROCESS_PRIVATE* = cint(0)
-  PTHREAD_SCOPE_PROCESS* = cint(1)
-  PTHREAD_SCOPE_SYSTEM* = cint(0)
-  POSIX_ASYNC_IO* = cint(1)
-  F_OK* = cint(0)
-  R_OK* = cint(4)
-  W_OK* = cint(2)
-  X_OK* = cint(1)
-  CS_PATH* = cint(0)
-  CS_POSIX_V6_ILP32_OFF32_CFLAGS* = cint(1116)
-  CS_POSIX_V6_ILP32_OFF32_LDFLAGS* = cint(1117)
-  CS_POSIX_V6_ILP32_OFF32_LIBS* = cint(1118)
-  CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* = cint(1120)
-  CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* = cint(1121)
-  CS_POSIX_V6_ILP32_OFFBIG_LIBS* = cint(1122)
-  CS_POSIX_V6_LP64_OFF64_CFLAGS* = cint(1124)
-  CS_POSIX_V6_LP64_OFF64_LDFLAGS* = cint(1125)
-  CS_POSIX_V6_LP64_OFF64_LIBS* = cint(1126)
-  CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* = cint(1128)
-  CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* = cint(1129)
-  CS_POSIX_V6_LPBIG_OFFBIG_LIBS* = cint(1130)
-  CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* = cint(1)
-  F_LOCK* = cint(1)
-  F_TEST* = cint(3)
-  F_TLOCK* = cint(2)
-  F_ULOCK* = cint(0)
-  PC_2_SYMLINKS* = cint(20)
-  PC_ALLOC_SIZE_MIN* = cint(18)
-  PC_ASYNC_IO* = cint(10)
-  PC_CHOWN_RESTRICTED* = cint(6)
-  PC_FILESIZEBITS* = cint(13)
-  PC_LINK_MAX* = cint(0)
-  PC_MAX_CANON* = cint(1)
-  PC_MAX_INPUT* = cint(2)
-  PC_NAME_MAX* = cint(3)
-  PC_NO_TRUNC* = cint(7)
-  PC_PATH_MAX* = cint(4)
-  PC_PIPE_BUF* = cint(5)
-  PC_PRIO_IO* = cint(11)
-  PC_REC_INCR_XFER_SIZE* = cint(14)
-  PC_REC_MIN_XFER_SIZE* = cint(16)
-  PC_REC_XFER_ALIGN* = cint(17)
-  PC_SYMLINK_MAX* = cint(19)
-  PC_SYNC_IO* = cint(9)
-  PC_VDISABLE* = cint(8)
-  SC_2_C_BIND* = cint(47)
-  SC_2_C_DEV* = cint(48)
-  SC_2_CHAR_TERM* = cint(95)
-  SC_2_FORT_DEV* = cint(49)
-  SC_2_FORT_RUN* = cint(50)
-  SC_2_LOCALEDEF* = cint(52)
-  SC_2_PBS* = cint(168)
-  SC_2_PBS_ACCOUNTING* = cint(169)
-  SC_2_PBS_CHECKPOINT* = cint(175)
-  SC_2_PBS_LOCATE* = cint(170)
-  SC_2_PBS_MESSAGE* = cint(171)
-  SC_2_PBS_TRACK* = cint(172)
-  SC_2_SW_DEV* = cint(51)
-  SC_2_UPE* = cint(97)
-  SC_2_VERSION* = cint(46)
-  SC_ADVISORY_INFO* = cint(132)
-  SC_AIO_LISTIO_MAX* = cint(23)
-  SC_AIO_MAX* = cint(24)
-  SC_AIO_PRIO_DELTA_MAX* = cint(25)
-  SC_ARG_MAX* = cint(0)
-  SC_ASYNCHRONOUS_IO* = cint(12)
-  SC_ATEXIT_MAX* = cint(87)
-  SC_BARRIERS* = cint(133)
-  SC_BC_BASE_MAX* = cint(36)
-  SC_BC_DIM_MAX* = cint(37)
-  SC_BC_SCALE_MAX* = cint(38)
-  SC_BC_STRING_MAX* = cint(39)
-  SC_CHILD_MAX* = cint(1)
-  SC_CLK_TCK* = cint(2)
-  SC_CLOCK_SELECTION* = cint(137)
-  SC_COLL_WEIGHTS_MAX* = cint(40)
-  SC_CPUTIME* = cint(138)
-  SC_DELAYTIMER_MAX* = cint(26)
-  SC_EXPR_NEST_MAX* = cint(42)
-  SC_FSYNC* = cint(15)
-  SC_GETGR_R_SIZE_MAX* = cint(69)
-  SC_GETPW_R_SIZE_MAX* = cint(70)
-  SC_HOST_NAME_MAX* = cint(180)
-  SC_IOV_MAX* = cint(60)
-  SC_IPV6* = cint(235)
-  SC_JOB_CONTROL* = cint(7)
-  SC_LINE_MAX* = cint(43)
-  SC_LOGIN_NAME_MAX* = cint(71)
-  SC_MAPPED_FILES* = cint(16)
-  SC_MEMLOCK* = cint(17)
-  SC_MEMLOCK_RANGE* = cint(18)
-  SC_MEMORY_PROTECTION* = cint(19)
-  SC_MESSAGE_PASSING* = cint(20)
-  SC_MONOTONIC_CLOCK* = cint(149)
-  SC_MQ_OPEN_MAX* = cint(27)
-  SC_MQ_PRIO_MAX* = cint(28)
-  SC_NGROUPS_MAX* = cint(3)
-  SC_OPEN_MAX* = cint(4)
-  SC_PAGE_SIZE* = cint(30)
-  SC_PRIORITIZED_IO* = cint(13)
-  SC_PRIORITY_SCHEDULING* = cint(10)
-  SC_RAW_SOCKETS* = cint(236)
-  SC_RE_DUP_MAX* = cint(44)
-  SC_READER_WRITER_LOCKS* = cint(153)
-  SC_REALTIME_SIGNALS* = cint(9)
-  SC_REGEXP* = cint(155)
-  SC_RTSIG_MAX* = cint(31)
-  SC_SAVED_IDS* = cint(8)
-  SC_SEM_NSEMS_MAX* = cint(32)
-  SC_SEM_VALUE_MAX* = cint(33)
-  SC_SEMAPHORES* = cint(21)
-  SC_SHARED_MEMORY_OBJECTS* = cint(22)
-  SC_SHELL* = cint(157)
-  SC_SIGQUEUE_MAX* = cint(34)
-  SC_SPAWN* = cint(159)
-  SC_SPIN_LOCKS* = cint(154)
-  SC_SPORADIC_SERVER* = cint(160)
-  SC_STREAM_MAX* = cint(5)
-  SC_SYMLOOP_MAX* = cint(173)
-  SC_SYNCHRONIZED_IO* = cint(14)
-  SC_THREAD_ATTR_STACKADDR* = cint(77)
-  SC_THREAD_ATTR_STACKSIZE* = cint(78)
-  SC_THREAD_CPUTIME* = cint(139)
-  SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(73)
-  SC_THREAD_KEYS_MAX* = cint(74)
-  SC_THREAD_PRIO_INHERIT* = cint(80)
-  SC_THREAD_PRIO_PROTECT* = cint(81)
-  SC_THREAD_PRIORITY_SCHEDULING* = cint(79)
-  SC_THREAD_PROCESS_SHARED* = cint(82)
-  SC_THREAD_SAFE_FUNCTIONS* = cint(68)
-  SC_THREAD_SPORADIC_SERVER* = cint(161)
-  SC_THREAD_STACK_MIN* = cint(75)
-  SC_THREAD_THREADS_MAX* = cint(76)
-  SC_THREADS* = cint(67)
-  SC_TIMEOUTS* = cint(164)
-  SC_TIMER_MAX* = cint(35)
-  SC_TIMERS* = cint(11)
-  SC_TRACE* = cint(181)
-  SC_TRACE_EVENT_FILTER* = cint(182)
-  SC_TRACE_INHERIT* = cint(183)
-  SC_TRACE_LOG* = cint(184)
-  SC_TTY_NAME_MAX* = cint(72)
-  SC_TYPED_MEMORY_OBJECTS* = cint(165)
-  SC_TZNAME_MAX* = cint(6)
-  SC_V6_ILP32_OFF32* = cint(176)
-  SC_V6_ILP32_OFFBIG* = cint(177)
-  SC_V6_LP64_OFF64* = cint(178)
-  SC_V6_LPBIG_OFFBIG* = cint(179)
-  SC_VERSION* = cint(29)
-  SC_XBS5_ILP32_OFF32* = cint(125)
-  SC_XBS5_ILP32_OFFBIG* = cint(126)
-  SC_XBS5_LP64_OFF64* = cint(127)
-  SC_XBS5_LPBIG_OFFBIG* = cint(128)
-  SC_XOPEN_CRYPT* = cint(92)
-  SC_XOPEN_ENH_I18N* = cint(93)
-  SC_XOPEN_LEGACY* = cint(129)
-  SC_XOPEN_REALTIME* = cint(130)
-  SC_XOPEN_REALTIME_THREADS* = cint(131)
-  SC_XOPEN_SHM* = cint(94)
-  SC_XOPEN_UNIX* = cint(91)
-  SC_XOPEN_VERSION* = cint(89)
-  SEEK_SET* = cint(0)
-  SEEK_CUR* = cint(1)
-  SEEK_END* = cint(2)
-  SEM_FAILED* = cast[pointer]((nil))
-  IPC_CREAT* = cint(512)
-  IPC_EXCL* = cint(1024)
-  IPC_NOWAIT* = cint(2048)
-  IPC_PRIVATE* = cint(0)
-  IPC_RMID* = cint(0)
-  IPC_SET* = cint(1)
-  IPC_STAT* = cint(2)
-  S_IFMT* = cint(61440)
-  S_IFBLK* = cint(24576)
-  S_IFCHR* = cint(8192)
-  S_IFIFO* = cint(4096)
-  S_IFREG* = cint(32768)
-  S_IFDIR* = cint(16384)
-  S_IFLNK* = cint(40960)
-  S_IFSOCK* = cint(49152)
-  S_IRWXU* = cint(448)
-  S_IRUSR* = cint(256)
-  S_IWUSR* = cint(128)
-  S_IXUSR* = cint(64)
-  S_IRWXG* = cint(56)
-  S_IRGRP* = cint(32)
-  S_IWGRP* = cint(16)
-  S_IXGRP* = cint(8)
-  S_IRWXO* = cint(7)
-  S_IROTH* = cint(4)
-  S_IWOTH* = cint(2)
-  S_IXOTH* = cint(1)
-  S_ISUID* = cint(2048)
-  S_ISGID* = cint(1024)
-  S_ISVTX* = cint(512)
-  ST_RDONLY* = cint(1)
-  ST_NOSUID* = cint(2)
-  PROT_READ* = cint(1)
-  PROT_WRITE* = cint(2)
-  PROT_EXEC* = cint(4)
-  PROT_NONE* = cint(0)
-  MAP_SHARED* = cint(1)
-  MAP_PRIVATE* = cint(2)
-  MAP_FIXED* = cint(16)
-  MS_ASYNC* = cint(1)
-  MS_SYNC* = cint(4)
-  MS_INVALIDATE* = cint(2)
-  MCL_CURRENT* = cint(1)
-  MCL_FUTURE* = cint(2)
-  MAP_FAILED* = cast[pointer](0xffffffffffffffff)
-  POSIX_MADV_NORMAL* = cint(0)
-  POSIX_MADV_SEQUENTIAL* = cint(2)
-  POSIX_MADV_RANDOM* = cint(1)
-  POSIX_MADV_WILLNEED* = cint(3)
-  POSIX_MADV_DONTNEED* = cint(4)
-  CLOCKS_PER_SEC* = clong(1000000)
-  CLOCK_PROCESS_CPUTIME_ID* = cint(2)
-  CLOCK_THREAD_CPUTIME_ID* = cint(3)
-  CLOCK_REALTIME* = cint(0)
-  TIMER_ABSTIME* = cint(1)
-  CLOCK_MONOTONIC* = cint(1)
-  WNOHANG* = cint(1)
-  WUNTRACED* = cint(2)
-  WEXITED* = cint(4)
-  WSTOPPED* = cint(2)
-  WCONTINUED* = cint(8)
-  WNOWAIT* = cint(16777216)
-  SIGEV_NONE* = cint(1)
-  SIGEV_SIGNAL* = cint(0)
-  SIGEV_THREAD* = cint(2)
-  SIGABRT* = cint(6)
-  SIGALRM* = cint(14)
-  SIGBUS* = cint(7)
-  SIGCHLD* = cint(17)
-  SIGCONT* = cint(18)
-  SIGFPE* = cint(8)
-  SIGHUP* = cint(1)
-  SIGILL* = cint(4)
-  SIGINT* = cint(2)
-  SIGKILL* = cint(9)
-  SIGPIPE* = cint(13)
-  SIGQUIT* = cint(3)
-  SIGSEGV* = cint(11)
-  SIGSTOP* = cint(19)
-  SIGTERM* = cint(15)
-  SIGTSTP* = cint(20)
-  SIGTTIN* = cint(21)
-  SIGTTOU* = cint(22)
-  SIGUSR1* = cint(10)
-  SIGUSR2* = cint(12)
-  SIGPOLL* = cint(29)
-  SIGPROF* = cint(27)
-  SIGSYS* = cint(31)
-  SIGTRAP* = cint(5)
-  SIGURG* = cint(23)
-  SIGVTALRM* = cint(26)
-  SIGXCPU* = cint(24)
-  SIGXFSZ* = cint(25)
-  SA_NOCLDSTOP* = cint(1)
-  SIG_BLOCK* = cint(0)
-  SIG_UNBLOCK* = cint(1)
-  SIG_SETMASK* = cint(2)
-  SA_ONSTACK* = cint(134217728)
-  SA_RESETHAND* = cint(-2147483648)
-  SA_RESTART* = cint(268435456)
-  SA_SIGINFO* = cint(4)
-  SA_NOCLDWAIT* = cint(2)
-  SA_NODEFER* = cint(1073741824)
-  SS_ONSTACK* = cint(1)
-  SS_DISABLE* = cint(2)
-  MINSIGSTKSZ* = cint(2048)
-  SIGSTKSZ* = cint(8192)
-  NL_SETD* = cint(1)
-  NL_CAT_LOCALE* = cint(1)
-  SCHED_FIFO* = cint(1)
-  SCHED_RR* = cint(2)
-  SCHED_OTHER* = cint(0)
-  FD_SETSIZE* = cint(1024)
-  IF_NAMESIZE* = cint(16)
-  SCM_RIGHTS* = cint(1)
-  SOCK_DGRAM* = cint(2)
-  SOCK_RAW* = cint(3)
-  SOCK_SEQPACKET* = cint(5)
-  SOCK_STREAM* = cint(1)
-  SOL_SOCKET* = cint(1)
-  SO_ACCEPTCONN* = cint(30)
-  SO_BROADCAST* = cint(6)
-  SO_DEBUG* = cint(1)
-  SO_DONTROUTE* = cint(5)
-  SO_ERROR* = cint(4)
-  SO_KEEPALIVE* = cint(9)
-  SO_LINGER* = cint(13)
-  SO_OOBINLINE* = cint(10)
-  SO_RCVBUF* = cint(8)
-  SO_RCVLOWAT* = cint(18)
-  SO_RCVTIMEO* = cint(20)
-  SO_REUSEADDR* = cint(2)
-  SO_SNDBUF* = cint(7)
-  SO_SNDLOWAT* = cint(19)
-  SO_SNDTIMEO* = cint(21)
-  SO_TYPE* = cint(3)
-  SOMAXCONN* = cint(128)
-  MSG_CTRUNC* = cint(8)
-  MSG_DONTROUTE* = cint(4)
-  MSG_EOR* = cint(128)
-  MSG_OOB* = cint(1)
-  MSG_PEEK* = cint(2)
-  MSG_TRUNC* = cint(32)
-  MSG_WAITALL* = cint(256)
-  AF_INET* = cint(2)
-  AF_INET6* = cint(10)
-  AF_UNIX* = cint(1)
-  AF_UNSPEC* = cint(0)
-  SHUT_RD* = cint(0)
-  SHUT_RDWR* = cint(2)
-  SHUT_WR* = cint(1)
-  IPPROTO_IP* = cint(0)
-  IPPROTO_IPV6* = cint(41)
-  IPPROTO_ICMP* = cint(1)
-  IPPROTO_RAW* = cint(255)
-  IPPROTO_TCP* = cint(6)
-  IPPROTO_UDP* = cint(17)
-  INADDR_ANY* = cint(0)
-  INADDR_BROADCAST* = cint(-1)
-  INET_ADDRSTRLEN* = cint(16)
-  IPV6_JOIN_GROUP* = cint(20)
-  IPV6_LEAVE_GROUP* = cint(21)
-  IPV6_MULTICAST_HOPS* = cint(18)
-  IPV6_MULTICAST_IF* = cint(17)
-  IPV6_MULTICAST_LOOP* = cint(19)
-  IPV6_UNICAST_HOPS* = cint(16)
-  IPV6_V6ONLY* = cint(26)
-  IPPORT_RESERVED* = cint(1024)
-  HOST_NOT_FOUND* = cint(1)
-  NO_DATA* = cint(4)
-  NO_RECOVERY* = cint(3)
-  TRY_AGAIN* = cint(2)
-  AI_PASSIVE* = cint(1)
-  AI_CANONNAME* = cint(2)
-  AI_NUMERICHOST* = cint(4)
-  AI_NUMERICSERV* = cint(1024)
-  AI_V4MAPPED* = cint(8)
-  AI_ALL* = cint(16)
-  AI_ADDRCONFIG* = cint(32)
-  NI_NOFQDN* = cint(4)
-  NI_NUMERICHOST* = cint(1)
-  NI_NAMEREQD* = cint(8)
-  NI_NUMERICSERV* = cint(2)
-  NI_DGRAM* = cint(16)
-  EAI_AGAIN* = cint(-3)
-  EAI_BADFLAGS* = cint(-1)
-  EAI_FAIL* = cint(-4)
-  EAI_FAMILY* = cint(-6)
-  EAI_MEMORY* = cint(-10)
-  EAI_NONAME* = cint(-2)
-  EAI_SERVICE* = cint(-8)
-  EAI_SOCKTYPE* = cint(-7)
-  EAI_SYSTEM* = cint(-11)
-  EAI_OVERFLOW* = cint(-12)
-  POLLIN* = cshort(1)
-  POLLPRI* = cshort(2)
-  POLLOUT* = cshort(4)
-  POLLERR* = cshort(8)
-  POLLHUP* = cshort(16)
-  POLLNVAL* = cshort(32)
-  POSIX_SPAWN_RESETIDS* = cint(1)
-  POSIX_SPAWN_SETPGROUP* = cint(2)
-  POSIX_SPAWN_SETSCHEDPARAM* = cint(16)
-  POSIX_SPAWN_SETSCHEDULER* = cint(32)
-  POSIX_SPAWN_SETSIGDEF* = cint(4)
-  POSIX_SPAWN_SETSIGMASK* = cint(8)
diff --git a/lib/posix/linux_consts.nim b/lib/posix/linux_consts.nim
deleted file mode 100644
index 2fadcd83b..000000000
--- a/lib/posix/linux_consts.nim
+++ /dev/null
@@ -1,620 +0,0 @@
-# Generated by detect.nim
-const
-  AIO_ALLDONE* = cint(2)
-  AIO_CANCELED* = cint(0)
-  AIO_NOTCANCELED* = cint(1)
-  LIO_NOP* = cint(2)
-  LIO_NOWAIT* = cint(1)
-  LIO_READ* = cint(0)
-  LIO_WAIT* = cint(0)
-  LIO_WRITE* = cint(1)
-  RTLD_LAZY* = cint(1)
-  RTLD_NOW* = cint(2)
-  RTLD_GLOBAL* = cint(256)
-  RTLD_LOCAL* = cint(0)
-  E2BIG* = cint(7)
-  EACCES* = cint(13)
-  EADDRINUSE* = cint(98)
-  EADDRNOTAVAIL* = cint(99)
-  EAFNOSUPPORT* = cint(97)
-  EAGAIN* = cint(11)
-  EALREADY* = cint(114)
-  EBADF* = cint(9)
-  EBADMSG* = cint(74)
-  EBUSY* = cint(16)
-  ECANCELED* = cint(125)
-  ECHILD* = cint(10)
-  ECONNABORTED* = cint(103)
-  ECONNREFUSED* = cint(111)
-  ECONNRESET* = cint(104)
-  EDEADLK* = cint(35)
-  EDESTADDRREQ* = cint(89)
-  EDOM* = cint(33)
-  EDQUOT* = cint(122)
-  EEXIST* = cint(17)
-  EFAULT* = cint(14)
-  EFBIG* = cint(27)
-  EHOSTUNREACH* = cint(113)
-  EIDRM* = cint(43)
-  EILSEQ* = cint(84)
-  EINPROGRESS* = cint(115)
-  EINTR* = cint(4)
-  EINVAL* = cint(22)
-  EIO* = cint(5)
-  EISCONN* = cint(106)
-  EISDIR* = cint(21)
-  ELOOP* = cint(40)
-  EMFILE* = cint(24)
-  EMLINK* = cint(31)
-  EMSGSIZE* = cint(90)
-  EMULTIHOP* = cint(72)
-  ENAMETOOLONG* = cint(36)
-  ENETDOWN* = cint(100)
-  ENETRESET* = cint(102)
-  ENETUNREACH* = cint(101)
-  ENFILE* = cint(23)
-  ENOBUFS* = cint(105)
-  ENODATA* = cint(61)
-  ENODEV* = cint(19)
-  ENOENT* = cint(2)
-  ENOEXEC* = cint(8)
-  ENOLCK* = cint(37)
-  ENOLINK* = cint(67)
-  ENOMEM* = cint(12)
-  ENOMSG* = cint(42)
-  ENOPROTOOPT* = cint(92)
-  ENOSPC* = cint(28)
-  ENOSR* = cint(63)
-  ENOSTR* = cint(60)
-  ENOSYS* = cint(38)
-  ENOTCONN* = cint(107)
-  ENOTDIR* = cint(20)
-  ENOTEMPTY* = cint(39)
-  ENOTSOCK* = cint(88)
-  ENOTSUP* = cint(95)
-  ENOTTY* = cint(25)
-  ENXIO* = cint(6)
-  EOPNOTSUPP* = cint(95)
-  EOVERFLOW* = cint(75)
-  EPERM* = cint(1)
-  EPIPE* = cint(32)
-  EPROTO* = cint(71)
-  EPROTONOSUPPORT* = cint(93)
-  EPROTOTYPE* = cint(91)
-  ERANGE* = cint(34)
-  EROFS* = cint(30)
-  ESPIPE* = cint(29)
-  ESRCH* = cint(3)
-  ESTALE* = cint(116)
-  ETIME* = cint(62)
-  ETIMEDOUT* = cint(110)
-  ETXTBSY* = cint(26)
-  EWOULDBLOCK* = cint(11)
-  EXDEV* = cint(18)
-  F_DUPFD* = cint(0)
-  F_GETFD* = cint(1)
-  F_SETFD* = cint(2)
-  F_GETFL* = cint(3)
-  F_SETFL* = cint(4)
-  F_GETLK* = cint(5)
-  F_SETLK* = cint(6)
-  F_SETLKW* = cint(7)
-  F_GETOWN* = cint(9)
-  F_SETOWN* = cint(8)
-  FD_CLOEXEC* = cint(1)
-  F_RDLCK* = cint(0)
-  F_UNLCK* = cint(2)
-  F_WRLCK* = cint(1)
-  O_CREAT* = cint(64)
-  O_EXCL* = cint(128)
-  O_NOCTTY* = cint(256)
-  O_TRUNC* = cint(512)
-  O_APPEND* = cint(1024)
-  O_DSYNC* = cint(4096)
-  O_NONBLOCK* = cint(2048)
-  O_RSYNC* = cint(4096)
-  O_SYNC* = cint(4096)
-  O_ACCMODE* = cint(3)
-  O_RDONLY* = cint(0)
-  O_RDWR* = cint(2)
-  O_WRONLY* = cint(1)
-  POSIX_FADV_NORMAL* = cint(0)
-  POSIX_FADV_SEQUENTIAL* = cint(2)
-  POSIX_FADV_RANDOM* = cint(1)
-  POSIX_FADV_WILLNEED* = cint(3)
-  POSIX_FADV_DONTNEED* = cint(4)
-  POSIX_FADV_NOREUSE* = cint(5)
-  FE_DIVBYZERO* = cint(4)
-  FE_INEXACT* = cint(32)
-  FE_INVALID* = cint(1)
-  FE_OVERFLOW* = cint(8)
-  FE_UNDERFLOW* = cint(16)
-  FE_ALL_EXCEPT* = cint(61)
-  FE_DOWNWARD* = cint(1024)
-  FE_TONEAREST* = cint(0)
-  FE_TOWARDZERO* = cint(3072)
-  FE_UPWARD* = cint(2048)
-  FE_DFL_ENV* = cast[pointer](0xffffffffffffffff)
-  MM_HARD* = cint(1)
-  MM_SOFT* = cint(2)
-  MM_FIRM* = cint(4)
-  MM_APPL* = cint(8)
-  MM_UTIL* = cint(16)
-  MM_OPSYS* = cint(32)
-  MM_RECOVER* = cint(64)
-  MM_NRECOV* = cint(128)
-  MM_HALT* = cint(1)
-  MM_ERROR* = cint(2)
-  MM_WARNING* = cint(3)
-  MM_INFO* = cint(4)
-  MM_NOSEV* = cint(0)
-  MM_PRINT* = cint(256)
-  MM_CONSOLE* = cint(512)
-  MM_OK* = cint(0)
-  MM_NOTOK* = cint(-1)
-  MM_NOMSG* = cint(1)
-  MM_NOCON* = cint(4)
-  FNM_NOMATCH* = cint(1)
-  FNM_PATHNAME* = cint(1)
-  FNM_PERIOD* = cint(4)
-  FNM_NOESCAPE* = cint(2)
-  FTW_F* = cint(0)
-  FTW_D* = cint(1)
-  FTW_DNR* = cint(2)
-  FTW_NS* = cint(3)
-  FTW_SL* = cint(4)
-  GLOB_APPEND* = cint(32)
-  GLOB_DOOFFS* = cint(8)
-  GLOB_ERR* = cint(1)
-  GLOB_MARK* = cint(2)
-  GLOB_NOCHECK* = cint(16)
-  GLOB_NOESCAPE* = cint(64)
-  GLOB_NOSORT* = cint(4)
-  GLOB_ABORTED* = cint(2)
-  GLOB_NOMATCH* = cint(3)
-  GLOB_NOSPACE* = cint(1)
-  GLOB_NOSYS* = cint(4)
-  CODESET* = cint(14)
-  D_T_FMT* = cint(131112)
-  D_FMT* = cint(131113)
-  T_FMT* = cint(131114)
-  T_FMT_AMPM* = cint(131115)
-  AM_STR* = cint(131110)
-  PM_STR* = cint(131111)
-  DAY_1* = cint(131079)
-  DAY_2* = cint(131080)
-  DAY_3* = cint(131081)
-  DAY_4* = cint(131082)
-  DAY_5* = cint(131083)
-  DAY_6* = cint(131084)
-  DAY_7* = cint(131085)
-  ABDAY_1* = cint(131072)
-  ABDAY_2* = cint(131073)
-  ABDAY_3* = cint(131074)
-  ABDAY_4* = cint(131075)
-  ABDAY_5* = cint(131076)
-  ABDAY_6* = cint(131077)
-  ABDAY_7* = cint(131078)
-  MON_1* = cint(131098)
-  MON_2* = cint(131099)
-  MON_3* = cint(131100)
-  MON_4* = cint(131101)
-  MON_5* = cint(131102)
-  MON_6* = cint(131103)
-  MON_7* = cint(131104)
-  MON_8* = cint(131105)
-  MON_9* = cint(131106)
-  MON_10* = cint(131107)
-  MON_11* = cint(131108)
-  MON_12* = cint(131109)
-  ABMON_1* = cint(131086)
-  ABMON_2* = cint(131087)
-  ABMON_3* = cint(131088)
-  ABMON_4* = cint(131089)
-  ABMON_5* = cint(131090)
-  ABMON_6* = cint(131091)
-  ABMON_7* = cint(131092)
-  ABMON_8* = cint(131093)
-  ABMON_9* = cint(131094)
-  ABMON_10* = cint(131095)
-  ABMON_11* = cint(131096)
-  ABMON_12* = cint(131097)
-  ERA* = cint(131116)
-  ERA_D_FMT* = cint(131118)
-  ERA_D_T_FMT* = cint(131120)
-  ERA_T_FMT* = cint(131121)
-  ALT_DIGITS* = cint(131119)
-  RADIXCHAR* = cint(65536)
-  THOUSEP* = cint(65537)
-  YESEXPR* = cint(327680)
-  NOEXPR* = cint(327681)
-  CRNCYSTR* = cint(262159)
-  LC_ALL* = cint(6)
-  LC_COLLATE* = cint(3)
-  LC_CTYPE* = cint(0)
-  LC_MESSAGES* = cint(5)
-  LC_MONETARY* = cint(4)
-  LC_NUMERIC* = cint(1)
-  LC_TIME* = cint(2)
-  PTHREAD_BARRIER_SERIAL_THREAD* = cint(-1)
-  PTHREAD_CANCEL_ASYNCHRONOUS* = cint(1)
-  PTHREAD_CANCEL_ENABLE* = cint(0)
-  PTHREAD_CANCEL_DEFERRED* = cint(0)
-  PTHREAD_CANCEL_DISABLE* = cint(1)
-  PTHREAD_CREATE_DETACHED* = cint(1)
-  PTHREAD_CREATE_JOINABLE* = cint(0)
-  PTHREAD_EXPLICIT_SCHED* = cint(1)
-  PTHREAD_INHERIT_SCHED* = cint(0)
-  PTHREAD_ONCE_INIT* = cint(0)
-  PTHREAD_PROCESS_SHARED* = cint(1)
-  PTHREAD_PROCESS_PRIVATE* = cint(0)
-  PTHREAD_SCOPE_PROCESS* = cint(1)
-  PTHREAD_SCOPE_SYSTEM* = cint(0)
-  POSIX_ASYNC_IO* = cint(1)
-  F_OK* = cint(0)
-  R_OK* = cint(4)
-  W_OK* = cint(2)
-  X_OK* = cint(1)
-  CS_PATH* = cint(0)
-  CS_POSIX_V6_ILP32_OFF32_CFLAGS* = cint(1116)
-  CS_POSIX_V6_ILP32_OFF32_LDFLAGS* = cint(1117)
-  CS_POSIX_V6_ILP32_OFF32_LIBS* = cint(1118)
-  CS_POSIX_V6_ILP32_OFFBIG_CFLAGS* = cint(1120)
-  CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS* = cint(1121)
-  CS_POSIX_V6_ILP32_OFFBIG_LIBS* = cint(1122)
-  CS_POSIX_V6_LP64_OFF64_CFLAGS* = cint(1124)
-  CS_POSIX_V6_LP64_OFF64_LDFLAGS* = cint(1125)
-  CS_POSIX_V6_LP64_OFF64_LIBS* = cint(1126)
-  CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS* = cint(1128)
-  CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS* = cint(1129)
-  CS_POSIX_V6_LPBIG_OFFBIG_LIBS* = cint(1130)
-  CS_POSIX_V6_WIDTH_RESTRICTED_ENVS* = cint(1)
-  F_LOCK* = cint(1)
-  F_TEST* = cint(3)
-  F_TLOCK* = cint(2)
-  F_ULOCK* = cint(0)
-  PC_2_SYMLINKS* = cint(20)
-  PC_ALLOC_SIZE_MIN* = cint(18)
-  PC_ASYNC_IO* = cint(10)
-  PC_CHOWN_RESTRICTED* = cint(6)
-  PC_FILESIZEBITS* = cint(13)
-  PC_LINK_MAX* = cint(0)
-  PC_MAX_CANON* = cint(1)
-  PC_MAX_INPUT* = cint(2)
-  PC_NAME_MAX* = cint(3)
-  PC_NO_TRUNC* = cint(7)
-  PC_PATH_MAX* = cint(4)
-  PC_PIPE_BUF* = cint(5)
-  PC_PRIO_IO* = cint(11)
-  PC_REC_INCR_XFER_SIZE* = cint(14)
-  PC_REC_MIN_XFER_SIZE* = cint(16)
-  PC_REC_XFER_ALIGN* = cint(17)
-  PC_SYMLINK_MAX* = cint(19)
-  PC_SYNC_IO* = cint(9)
-  PC_VDISABLE* = cint(8)
-  SC_2_C_BIND* = cint(47)
-  SC_2_C_DEV* = cint(48)
-  SC_2_CHAR_TERM* = cint(95)
-  SC_2_FORT_DEV* = cint(49)
-  SC_2_FORT_RUN* = cint(50)
-  SC_2_LOCALEDEF* = cint(52)
-  SC_2_PBS* = cint(168)
-  SC_2_PBS_ACCOUNTING* = cint(169)
-  SC_2_PBS_CHECKPOINT* = cint(175)
-  SC_2_PBS_LOCATE* = cint(170)
-  SC_2_PBS_MESSAGE* = cint(171)
-  SC_2_PBS_TRACK* = cint(172)
-  SC_2_SW_DEV* = cint(51)
-  SC_2_UPE* = cint(97)
-  SC_2_VERSION* = cint(46)
-  SC_ADVISORY_INFO* = cint(132)
-  SC_AIO_LISTIO_MAX* = cint(23)
-  SC_AIO_MAX* = cint(24)
-  SC_AIO_PRIO_DELTA_MAX* = cint(25)
-  SC_ARG_MAX* = cint(0)
-  SC_ASYNCHRONOUS_IO* = cint(12)
-  SC_ATEXIT_MAX* = cint(87)
-  SC_BARRIERS* = cint(133)
-  SC_BC_BASE_MAX* = cint(36)
-  SC_BC_DIM_MAX* = cint(37)
-  SC_BC_SCALE_MAX* = cint(38)
-  SC_BC_STRING_MAX* = cint(39)
-  SC_CHILD_MAX* = cint(1)
-  SC_CLK_TCK* = cint(2)
-  SC_CLOCK_SELECTION* = cint(137)
-  SC_COLL_WEIGHTS_MAX* = cint(40)
-  SC_CPUTIME* = cint(138)
-  SC_DELAYTIMER_MAX* = cint(26)
-  SC_EXPR_NEST_MAX* = cint(42)
-  SC_FSYNC* = cint(15)
-  SC_GETGR_R_SIZE_MAX* = cint(69)
-  SC_GETPW_R_SIZE_MAX* = cint(70)
-  SC_HOST_NAME_MAX* = cint(180)
-  SC_IOV_MAX* = cint(60)
-  SC_IPV6* = cint(235)
-  SC_JOB_CONTROL* = cint(7)
-  SC_LINE_MAX* = cint(43)
-  SC_LOGIN_NAME_MAX* = cint(71)
-  SC_MAPPED_FILES* = cint(16)
-  SC_MEMLOCK* = cint(17)
-  SC_MEMLOCK_RANGE* = cint(18)
-  SC_MEMORY_PROTECTION* = cint(19)
-  SC_MESSAGE_PASSING* = cint(20)
-  SC_MONOTONIC_CLOCK* = cint(149)
-  SC_MQ_OPEN_MAX* = cint(27)
-  SC_MQ_PRIO_MAX* = cint(28)
-  SC_NGROUPS_MAX* = cint(3)
-  SC_OPEN_MAX* = cint(4)
-  SC_PAGE_SIZE* = cint(30)
-  SC_PRIORITIZED_IO* = cint(13)
-  SC_PRIORITY_SCHEDULING* = cint(10)
-  SC_RAW_SOCKETS* = cint(236)
-  SC_RE_DUP_MAX* = cint(44)
-  SC_READER_WRITER_LOCKS* = cint(153)
-  SC_REALTIME_SIGNALS* = cint(9)
-  SC_REGEXP* = cint(155)
-  SC_RTSIG_MAX* = cint(31)
-  SC_SAVED_IDS* = cint(8)
-  SC_SEM_NSEMS_MAX* = cint(32)
-  SC_SEM_VALUE_MAX* = cint(33)
-  SC_SEMAPHORES* = cint(21)
-  SC_SHARED_MEMORY_OBJECTS* = cint(22)
-  SC_SHELL* = cint(157)
-  SC_SIGQUEUE_MAX* = cint(34)
-  SC_SPAWN* = cint(159)
-  SC_SPIN_LOCKS* = cint(154)
-  SC_SPORADIC_SERVER* = cint(160)
-  SC_STREAM_MAX* = cint(5)
-  SC_SYMLOOP_MAX* = cint(173)
-  SC_SYNCHRONIZED_IO* = cint(14)
-  SC_THREAD_ATTR_STACKADDR* = cint(77)
-  SC_THREAD_ATTR_STACKSIZE* = cint(78)
-  SC_THREAD_CPUTIME* = cint(139)
-  SC_THREAD_DESTRUCTOR_ITERATIONS* = cint(73)
-  SC_THREAD_KEYS_MAX* = cint(74)
-  SC_THREAD_PRIO_INHERIT* = cint(80)
-  SC_THREAD_PRIO_PROTECT* = cint(81)
-  SC_THREAD_PRIORITY_SCHEDULING* = cint(79)
-  SC_THREAD_PROCESS_SHARED* = cint(82)
-  SC_THREAD_SAFE_FUNCTIONS* = cint(68)
-  SC_THREAD_SPORADIC_SERVER* = cint(161)
-  SC_THREAD_STACK_MIN* = cint(75)
-  SC_THREAD_THREADS_MAX* = cint(76)
-  SC_THREADS* = cint(67)
-  SC_TIMEOUTS* = cint(164)
-  SC_TIMER_MAX* = cint(35)
-  SC_TIMERS* = cint(11)
-  SC_TRACE* = cint(181)
-  SC_TRACE_EVENT_FILTER* = cint(182)
-  SC_TRACE_INHERIT* = cint(183)
-  SC_TRACE_LOG* = cint(184)
-  SC_TTY_NAME_MAX* = cint(72)
-  SC_TYPED_MEMORY_OBJECTS* = cint(165)
-  SC_TZNAME_MAX* = cint(6)
-  SC_V6_ILP32_OFF32* = cint(176)
-  SC_V6_ILP32_OFFBIG* = cint(177)
-  SC_V6_LP64_OFF64* = cint(178)
-  SC_V6_LPBIG_OFFBIG* = cint(179)
-  SC_VERSION* = cint(29)
-  SC_XBS5_ILP32_OFF32* = cint(125)
-  SC_XBS5_ILP32_OFFBIG* = cint(126)
-  SC_XBS5_LP64_OFF64* = cint(127)
-  SC_XBS5_LPBIG_OFFBIG* = cint(128)
-  SC_XOPEN_CRYPT* = cint(92)
-  SC_XOPEN_ENH_I18N* = cint(93)
-  SC_XOPEN_LEGACY* = cint(129)
-  SC_XOPEN_REALTIME* = cint(130)
-  SC_XOPEN_REALTIME_THREADS* = cint(131)
-  SC_XOPEN_SHM* = cint(94)
-  SC_XOPEN_UNIX* = cint(91)
-  SC_XOPEN_VERSION* = cint(89)
-  SEEK_SET* = cint(0)
-  SEEK_CUR* = cint(1)
-  SEEK_END* = cint(2)
-  SEM_FAILED* = cast[pointer]((nil))
-  IPC_CREAT* = cint(512)
-  IPC_EXCL* = cint(1024)
-  IPC_NOWAIT* = cint(2048)
-  IPC_PRIVATE* = cint(0)
-  IPC_RMID* = cint(0)
-  IPC_SET* = cint(1)
-  IPC_STAT* = cint(2)
-  S_IFMT* = cint(61440)
-  S_IFBLK* = cint(24576)
-  S_IFCHR* = cint(8192)
-  S_IFIFO* = cint(4096)
-  S_IFREG* = cint(32768)
-  S_IFDIR* = cint(16384)
-  S_IFLNK* = cint(40960)
-  S_IFSOCK* = cint(49152)
-  S_IRWXU* = cint(448)
-  S_IRUSR* = cint(256)
-  S_IWUSR* = cint(128)
-  S_IXUSR* = cint(64)
-  S_IRWXG* = cint(56)
-  S_IRGRP* = cint(32)
-  S_IWGRP* = cint(16)
-  S_IXGRP* = cint(8)
-  S_IRWXO* = cint(7)
-  S_IROTH* = cint(4)
-  S_IWOTH* = cint(2)
-  S_IXOTH* = cint(1)
-  S_ISUID* = cint(2048)
-  S_ISGID* = cint(1024)
-  S_ISVTX* = cint(512)
-  ST_RDONLY* = cint(1)
-  ST_NOSUID* = cint(2)
-  PROT_READ* = cint(1)
-  PROT_WRITE* = cint(2)
-  PROT_EXEC* = cint(4)
-  PROT_NONE* = cint(0)
-  MAP_SHARED* = cint(1)
-  MAP_PRIVATE* = cint(2)
-  MAP_FIXED* = cint(16)
-  MS_ASYNC* = cint(1)
-  MS_SYNC* = cint(4)
-  MS_INVALIDATE* = cint(2)
-  MCL_CURRENT* = cint(1)
-  MCL_FUTURE* = cint(2)
-  MAP_FAILED* = cast[pointer](0xffffffffffffffff)
-  POSIX_MADV_NORMAL* = cint(0)
-  POSIX_MADV_SEQUENTIAL* = cint(2)
-  POSIX_MADV_RANDOM* = cint(1)
-  POSIX_MADV_WILLNEED* = cint(3)
-  POSIX_MADV_DONTNEED* = cint(4)
-  CLOCKS_PER_SEC* = clong(1000000)
-  CLOCK_PROCESS_CPUTIME_ID* = cint(2)
-  CLOCK_THREAD_CPUTIME_ID* = cint(3)
-  CLOCK_REALTIME* = cint(0)
-  TIMER_ABSTIME* = cint(1)
-  CLOCK_MONOTONIC* = cint(1)
-  WNOHANG* = cint(1)
-  WUNTRACED* = cint(2)
-  WEXITED* = cint(4)
-  WSTOPPED* = cint(2)
-  WCONTINUED* = cint(8)
-  WNOWAIT* = cint(16777216)
-  SIGEV_NONE* = cint(1)
-  SIGEV_SIGNAL* = cint(0)
-  SIGEV_THREAD* = cint(2)
-  SIGABRT* = cint(6)
-  SIGALRM* = cint(14)
-  SIGBUS* = cint(7)
-  SIGCHLD* = cint(17)
-  SIGCONT* = cint(18)
-  SIGFPE* = cint(8)
-  SIGHUP* = cint(1)
-  SIGILL* = cint(4)
-  SIGINT* = cint(2)
-  SIGKILL* = cint(9)
-  SIGPIPE* = cint(13)
-  SIGQUIT* = cint(3)
-  SIGSEGV* = cint(11)
-  SIGSTOP* = cint(19)
-  SIGTERM* = cint(15)
-  SIGTSTP* = cint(20)
-  SIGTTIN* = cint(21)
-  SIGTTOU* = cint(22)
-  SIGUSR1* = cint(10)
-  SIGUSR2* = cint(12)
-  SIGPOLL* = cint(29)
-  SIGPROF* = cint(27)
-  SIGSYS* = cint(31)
-  SIGTRAP* = cint(5)
-  SIGURG* = cint(23)
-  SIGVTALRM* = cint(26)
-  SIGXCPU* = cint(24)
-  SIGXFSZ* = cint(25)
-  SA_NOCLDSTOP* = cint(1)
-  SIG_BLOCK* = cint(0)
-  SIG_UNBLOCK* = cint(1)
-  SIG_SETMASK* = cint(2)
-  SA_ONSTACK* = cint(134217728)
-  SA_RESETHAND* = cint(-2147483648)
-  SA_RESTART* = cint(268435456)
-  SA_SIGINFO* = cint(4)
-  SA_NOCLDWAIT* = cint(2)
-  SA_NODEFER* = cint(1073741824)
-  SS_ONSTACK* = cint(1)
-  SS_DISABLE* = cint(2)
-  MINSIGSTKSZ* = cint(2048)
-  SIGSTKSZ* = cint(8192)
-  NL_SETD* = cint(1)
-  NL_CAT_LOCALE* = cint(1)
-  SCHED_FIFO* = cint(1)
-  SCHED_RR* = cint(2)
-  SCHED_OTHER* = cint(0)
-  FD_SETSIZE* = cint(1024)
-  IF_NAMESIZE* = cint(16)
-  SCM_RIGHTS* = cint(1)
-  SOCK_DGRAM* = cint(2)
-  SOCK_RAW* = cint(3)
-  SOCK_SEQPACKET* = cint(5)
-  SOCK_STREAM* = cint(1)
-  SOL_SOCKET* = cint(1)
-  SO_ACCEPTCONN* = cint(30)
-  SO_BROADCAST* = cint(6)
-  SO_DEBUG* = cint(1)
-  SO_DONTROUTE* = cint(5)
-  SO_ERROR* = cint(4)
-  SO_KEEPALIVE* = cint(9)
-  SO_LINGER* = cint(13)
-  SO_OOBINLINE* = cint(10)
-  SO_RCVBUF* = cint(8)
-  SO_RCVLOWAT* = cint(18)
-  SO_RCVTIMEO* = cint(20)
-  SO_REUSEADDR* = cint(2)
-  SO_SNDBUF* = cint(7)
-  SO_SNDLOWAT* = cint(19)
-  SO_SNDTIMEO* = cint(21)
-  SO_TYPE* = cint(3)
-  SOMAXCONN* = cint(128)
-  MSG_CTRUNC* = cint(8)
-  MSG_DONTROUTE* = cint(4)
-  MSG_EOR* = cint(128)
-  MSG_OOB* = cint(1)
-  MSG_PEEK* = cint(2)
-  MSG_TRUNC* = cint(32)
-  MSG_WAITALL* = cint(256)
-  AF_INET* = cint(2)
-  AF_INET6* = cint(10)
-  AF_UNIX* = cint(1)
-  AF_UNSPEC* = cint(0)
-  SHUT_RD* = cint(0)
-  SHUT_RDWR* = cint(2)
-  SHUT_WR* = cint(1)
-  IPPROTO_IP* = cint(0)
-  IPPROTO_IPV6* = cint(41)
-  IPPROTO_ICMP* = cint(1)
-  IPPROTO_RAW* = cint(255)
-  IPPROTO_TCP* = cint(6)
-  IPPROTO_UDP* = cint(17)
-  INADDR_ANY* = cint(0)
-  INADDR_BROADCAST* = cint(-1)
-  INET_ADDRSTRLEN* = cint(16)
-  IPV6_JOIN_GROUP* = cint(20)
-  IPV6_LEAVE_GROUP* = cint(21)
-  IPV6_MULTICAST_HOPS* = cint(18)
-  IPV6_MULTICAST_IF* = cint(17)
-  IPV6_MULTICAST_LOOP* = cint(19)
-  IPV6_UNICAST_HOPS* = cint(16)
-  IPV6_V6ONLY* = cint(26)
-  IPPORT_RESERVED* = cint(1024)
-  HOST_NOT_FOUND* = cint(1)
-  NO_DATA* = cint(4)
-  NO_RECOVERY* = cint(3)
-  TRY_AGAIN* = cint(2)
-  AI_PASSIVE* = cint(1)
-  AI_CANONNAME* = cint(2)
-  AI_NUMERICHOST* = cint(4)
-  AI_NUMERICSERV* = cint(1024)
-  AI_V4MAPPED* = cint(8)
-  AI_ALL* = cint(16)
-  AI_ADDRCONFIG* = cint(32)
-  NI_NOFQDN* = cint(4)
-  NI_NUMERICHOST* = cint(1)
-  NI_NAMEREQD* = cint(8)
-  NI_NUMERICSERV* = cint(2)
-  NI_DGRAM* = cint(16)
-  EAI_AGAIN* = cint(-3)
-  EAI_BADFLAGS* = cint(-1)
-  EAI_FAIL* = cint(-4)
-  EAI_FAMILY* = cint(-6)
-  EAI_MEMORY* = cint(-10)
-  EAI_NONAME* = cint(-2)
-  EAI_SERVICE* = cint(-8)
-  EAI_SOCKTYPE* = cint(-7)
-  EAI_SYSTEM* = cint(-11)
-  EAI_OVERFLOW* = cint(-12)
-  POLLIN* = cshort(1)
-  POLLPRI* = cshort(2)
-  POLLOUT* = cshort(4)
-  POLLERR* = cshort(8)
-  POLLHUP* = cshort(16)
-  POLLNVAL* = cshort(32)
-  POSIX_SPAWN_RESETIDS* = cint(1)
-  POSIX_SPAWN_SETPGROUP* = cint(2)
-  POSIX_SPAWN_SETSCHEDPARAM* = cint(16)
-  POSIX_SPAWN_SETSCHEDULER* = cint(32)
-  POSIX_SPAWN_SETSIGDEF* = cint(4)
-  POSIX_SPAWN_SETSIGMASK* = cint(8)
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index e71e8a003..42cbbba75 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -26,33 +26,37 @@
 ## This library relies on the header files of your C compiler. Thus the

 ## resulting C code will just include <XYZ.h> and *not* define the

 ## symbols declared here.

+
+from times import TTime
 

 const

   hasSpawnH = defined(linux)

   hasAioH = defined(linux)

-

+
+when false:

+  const

+    C_IRUSR = 0c000400 ## Read by owner.

+    C_IWUSR = 0c000200 ## Write by owner.

+    C_IXUSR = 0c000100 ## Execute by owner.

+    C_IRGRP = 0c000040 ## Read by group.

+    C_IWGRP = 0c000020 ## Write by group.

+    C_IXGRP = 0c000010 ## Execute by group.

+    C_IROTH = 0c000004 ## Read by others.

+    C_IWOTH = 0c000002 ## Write by others.

+    C_IXOTH = 0c000001 ## Execute by others.

+    C_ISUID = 0c004000 ## Set user ID.

+    C_ISGID = 0c002000 ## Set group ID.

+    C_ISVTX = 0c001000 ## On directories, restricted deletion flag.

+    C_ISDIR = 0c040000 ## Directory.

+    C_ISFIFO = 0c010000 ##FIFO.

+    C_ISREG = 0c100000 ## Regular file.

+    C_ISBLK = 0c060000 ## Block special.

+    C_ISCHR = 0c020000 ## Character special.

+    C_ISCTG = 0c110000 ## Reserved.

+    C_ISLNK = 0c120000 ## Symbolic link.</p>

+    C_ISSOCK = 0c140000 ## Socket.

+
 const

-  C_IRUSR* = 0c000400 ## Read by owner.

-  C_IWUSR* = 0c000200 ## Write by owner.

-  C_IXUSR* = 0c000100 ## Execute by owner.

-  C_IRGRP* = 0c000040 ## Read by group.

-  C_IWGRP* = 0c000020 ## Write by group.

-  C_IXGRP* = 0c000010 ## Execute by group.

-  C_IROTH* = 0c000004 ## Read by others.

-  C_IWOTH* = 0c000002 ## Write by others.

-  C_IXOTH* = 0c000001 ## Execute by others.

-  C_ISUID* = 0c004000 ## Set user ID.

-  C_ISGID* = 0c002000 ## Set group ID.

-  C_ISVTX* = 0c001000 ## On directories, restricted deletion flag.

-  C_ISDIR* = 0c040000 ## Directory.

-  C_ISFIFO* = 0c010000 ##FIFO.

-  C_ISREG* = 0c100000 ## Regular file.

-  C_ISBLK* = 0c060000 ## Block special.

-  C_ISCHR* = 0c020000 ## Character special.

-  C_ISCTG* = 0c110000 ## Reserved.

-  C_ISLNK* = 0c120000 ## Symbolic link.</p>

-  C_ISSOCK* = 0c140000 ## Socket.

-

   MM_NULLLBL* = nil

   MM_NULLSEV* = 0

   MM_NULLMC* = 0

@@ -104,9 +108,9 @@ type
     

   TGlob* {.importc: "glob_t", header: "<glob.h>", 
            final, pure.} = object ## glob_t

-    gl_pathc*: int         ## Count of paths matched by pattern. 

-    gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames. 

-    gl_offs*: int          ## Slots to reserve at the beginning of gl_pathv. 

+    gl_pathc*: int          ## Count of paths matched by pattern. 

+    gl_pathv*: cstringArray ## Pointer to a list of matched pathnames. 

+    gl_offs*: int           ## Slots to reserve at the beginning of gl_pathv. 

   

   TGroup* {.importc: "struct group", header: "<grp.h>", 
             final, pure.} = object ## struct group

@@ -198,7 +202,7 @@ type
                        header: "<sys/types.h>".} = int

   Tpthread* {.importc: "pthread_t", header: "<sys/types.h>".} = int

   Tsuseconds* {.importc: "suseconds_t", header: "<sys/types.h>".} = int

-  Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int

+  #Ttime* {.importc: "time_t", header: "<sys/types.h>".} = int

   Ttimer* {.importc: "timer_t", header: "<sys/types.h>".} = int

   Ttrace_attr* {.importc: "trace_attr_t", header: "<sys/types.h>".} = int

   Ttrace_event_id* {.importc: "trace_event_id_t", 
@@ -2431,4 +2435,7 @@ proc setservent*(a1: cint) {.importc, header: "<netdb.h>".}
 proc poll*(a1: ptr Tpollfd, a2: Tnfds, a3: int): cint {.
   importc, header: "<poll.h>".}
 
+proc realpath*(name, resolved: CString): CString {.
+  importc: "realpath", header: "<stdlib.h>".}
+
 
diff --git a/lib/powerpc.asm.in b/lib/powerpc.asm.in
deleted file mode 100644
index 107f887ab..000000000
--- a/lib/powerpc.asm.in
+++ /dev/null
@@ -1,35 +0,0 @@
-; This contains the CPU-dependant variants of some routines.

-; (C) 2005 Andreas Rumpf

-; This code was inspired by the Freepascal compiler's sources

-; All routines here have the _cdecl calling convention because

-; that is the only convention any C compiler supports.

-

-\python{

-def c(name): 

-  if os.name == 'posix':

-    return name

-  else:

-    return "_" + name

-}

-

-segment code

-

-global \c{cpu_inc_locked}

-global \c{cpu_dec_locked}

-

-\c{cpu_dec_locked}: 

-; input:  address of arg in r3 

-  .LDecLockedLoop:

-    lwarx   r10,0,r3

-    subi    r10,r10,1

-    stwcx.  r10,0,r3

-    bne-    .LDecLockedLoop

-    cntlzw  r3,r10

-    srwi    r3,r3,5

-     

-\c{cpu_inc_locked}:

-  .LIncLockedLoop:

-    lwarx   r10,0,r3

-    addi    r10,r10,1

-    stwcx.  r10,0,r3

-    bne-    .LIncLockedLoop

diff --git a/lib/base/cgi.nim b/lib/pure/cgi.nim
index 5cf6d0bfa..5cf6d0bfa 100644
--- a/lib/base/cgi.nim
+++ b/lib/pure/cgi.nim
diff --git a/lib/complex.nim b/lib/pure/complex.nim
index f50ff4bd0..f50ff4bd0 100644
--- a/lib/complex.nim
+++ b/lib/pure/complex.nim
diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim
new file mode 100644
index 000000000..592073e3d
--- /dev/null
+++ b/lib/pure/dynlib.nim
@@ -0,0 +1,84 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2009 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module implements the ability to access symbols from shared
+## libraries. On POSIX this uses the ``dlsym`` mechanism, on 
+## Windows ``LoadLibrary``. 
+
+type
+  TLibHandle* = pointer ## a handle to a dynamically loaded library
+
+proc LoadLib*(path: string): TLibHandle
+  ## loads a library from `path`. Returns nil if the library could not 
+  ## be loaded.
+
+proc UnloadLib*(lib: TLibHandle)
+  ## unloads the library `lib`
+
+proc symAddr*(lib: TLibHandle, name: string): pointer
+  ## retrieves the address of a procedure/variable from `lib`. Returns nil
+  ## if the symbol could not be found.
+
+proc checkedSymAddr*(lib: TLibHandle, name: string): pointer =
+  ## retrieves the address of a procedure/variable from `lib`. Raises
+  ## `EInvalidLibrary` if the symbol could not be found.
+  result = symAddr(lib, name)
+  if result == nil: 
+    var e: ref EInvalidLibrary
+    new(e)
+    e.msg = "could not find symbol: " & name
+    raise e
+
+when defined(posix):
+  #
+  # =========================================================================
+  # This is an implementation based on the dlfcn interface.
+  # The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+  # NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
+  # as an emulation layer on top of native functions.
+  # =========================================================================
+  #
+  var
+    RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int
+
+  proc dlclose(lib: TLibHandle) {.importc, header: "<dlfcn.h>".}
+  proc dlopen(path: CString, mode: int): TLibHandle {.
+      importc, header: "<dlfcn.h>".}
+  proc dlsym(lib: TLibHandle, name: cstring): pointer {.
+      importc, header: "<dlfcn.h>".}
+
+  proc LoadLib(path: string): TLibHandle = return dlopen(path, RTLD_NOW)
+  proc UnloadLib(lib: TLibHandle) = dlclose(lib)
+  proc symAddr(lib: TLibHandle, name: string): pointer = 
+    return dlsym(lib, name)
+
+elif defined(windows) or defined(dos):
+  #
+  # =======================================================================
+  # Native Windows Implementation
+  # =======================================================================
+  #
+  type
+    THINSTANCE {.importc: "HINSTANCE".} = pointer
+
+  proc FreeLibrary(lib: THINSTANCE) {.importc, header: "<windows.h>", stdcall.}
+  proc winLoadLibrary(path: cstring): THINSTANCE {.
+      importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
+  proc GetProcAddress(lib: THINSTANCE, name: cstring): pointer {.
+      importc: "GetProcAddress", header: "<windows.h>", stdcall.}
+
+  proc LoadLib(path: string): TLibHandle =
+    result = cast[TLibHandle](winLoadLibrary(path))
+  proc UnloadLib(lib: TLibHandle) = FreeLibrary(cast[THINSTANCE](lib))
+
+  proc symAddr(lib: TLibHandle, name: string): pointer =
+    result = GetProcAddress(cast[THINSTANCE](lib), name)
+
+else:
+  {.error: "no implementation for dynlib".}
diff --git a/lib/hashes.nim b/lib/pure/hashes.nim
index 1593119bd..1593119bd 100644
--- a/lib/hashes.nim
+++ b/lib/pure/hashes.nim
diff --git a/lib/lexbase.nim b/lib/pure/lexbase.nim
index bb207e92a..bb207e92a 100644
--- a/lib/lexbase.nim
+++ b/lib/pure/lexbase.nim
diff --git a/lib/macros.nim b/lib/pure/macros.nim
index 2b75a1545..ce026a832 100644
--- a/lib/macros.nim
+++ b/lib/pure/macros.nim
@@ -64,19 +64,19 @@ type
     nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, nnkBlockType, 
     nnkVm, nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, 
     nnkRecList, nnkRecCase, nnkRecWhen, nnkRefTy, 
-    nnkPtrTy, nnkVarTy, nnkProcTy, nnkEnumTy, 
-    nnkEnumFieldDef, nnkReturnToken
+    nnkPtrTy, nnkVarTy, nnkAbstractTy, nnkProcTy, 
+    nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
   TNimNodeKinds* = set[TNimrodNodeKind]
   TNimrodTypeKind* = enum
     ntyNone, ntyBool, ntyChar, ntyEmpty, 
     ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst, 
-    ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray, 
-    ntyObject, ntyTuple, ntySet, ntyRange, 
-    ntyPtr, ntyRef, ntyVar, ntySequence, 
-    ntyProc, ntyPointer, ntyOpenArray, ntyString, 
-    ntyCString, ntyForward, ntyInt, ntyInt8, 
-    ntyInt16, ntyInt32, ntyInt64, ntyFloat, 
-    ntyFloat32, ntyFloat64, ntyFloat128
+    ntyGenericParam, ntyAbstract, ntyEnum, ntyOrdinal, 
+    ntyArray, ntyObject, ntyTuple, ntySet, 
+    ntyRange, ntyPtr, ntyRef, ntyVar, 
+    ntySequence, ntyProc, ntyPointer, ntyOpenArray, 
+    ntyString, ntyCString, ntyForward, ntyInt, 
+    ntyInt8, ntyInt16, ntyInt32, ntyInt64, 
+    ntyFloat, ntyFloat32, ntyFloat64, ntyFloat128
   TNimTypeKinds* = set[TNimrodTypeKind]
   TNimrodSymKind* = enum
     nskUnknownSym, nskConditional, nskDynLib, nskParam, 
diff --git a/lib/math.nim b/lib/pure/math.nim
index bc180f72c..a3e57e403 100644
--- a/lib/math.nim
+++ b/lib/pure/math.nim
@@ -86,7 +86,7 @@ proc nextPowerOfTwo*(x: int): int =
 proc countBits*(n: int32): int {.noSideEffect.}
   ## counts the set bits in `n`.
 
-include cntbits
+include "system/cntbits"
 
 proc sum*[T](x: openarray[T]): T {.noSideEffect.} = 
   ## computes the sum of the elements in `x`. 
diff --git a/lib/pure/md5.nim b/lib/pure/md5.nim
new file mode 100644
index 000000000..d9bb92949
--- /dev/null
+++ b/lib/pure/md5.nim
@@ -0,0 +1,245 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2009 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Module for computing MD5 checksums.
+
+type 
+  MD5State = array[0..3, int32]
+  MD5Block = array[0..15, int32]
+  MD5CBits = array[0..7, int8]
+  MD5Digest* = array[0..15, int8]
+  MD5Buffer = array[0..63, int8]
+  MD5Context* {.final.} = object 
+    State: MD5State
+    Count: array[0..1, int32]
+    Buffer: MD5Buffer
+
+const 
+  padding: cstring = "\x80\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0\0\0\0\0" &
+                     "\0\0\0\0"
+
+proc F(x, y, z: int32): int32 {.inline.} = 
+  Result = (x and y) or ((not x) and z)
+
+proc G(x, y, z: int32): int32 {.inline.} = 
+  Result = (x and z) or (y and (not z))
+
+proc H(x, y, z: int32): int32 {.inline.} = 
+  Result = x xor y xor z
+
+proc I(x, y, z: int32): int32 {.inline.} = 
+  Result = y xor (x or (not z))
+
+proc rot(x: var int32, n: int8) {.inline.} = 
+  x = toU32(x shl ze(n)) or (x shr toU32(32 -% ze(n)))
+
+proc FF(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = 
+  a = a +% F(b, c, d) +% x +% ac
+  rot(a, s)
+  a = a +% b
+
+proc GG(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = 
+  a = a +% G(b, c, d) +% x +% ac
+  rot(a, s)
+  a = a +% b
+
+proc HH(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = 
+  a = a +% H(b, c, d) +% x +% ac
+  rot(a, s)
+  a = a +% b
+
+proc II(a: var int32, b, c, d, x: int32, s: int8, ac: int32) = 
+  a = a +% I(b, c, d) +% x +% ac
+  rot(a, s)
+  a = a +% b
+
+proc encode(dest: var MD5Block, src: cstring) = 
+  var j = 0
+  for i in 0..high(dest):
+    dest[i] = toU32(ord(src[j]) or 
+                ord(src[j+1]) shl 8 or
+                ord(src[j+2]) shl 16 or
+                ord(src[j+3]) shl 24)
+    inc(j, 4)
+
+proc decode(dest: var openarray[int8], src: openarray[int32]) = 
+  var i = 0
+  for j in 0..high(src):
+    dest[i] = toU8(src[j] and 0xff'i32)
+    dest[i+1] = toU8(src[j] shr 8'i32 and 0xff'i32)
+    dest[i+2] = toU8(src[j] shr 16'i32 and 0xff'i32)
+    dest[i+3] = toU8(src[j] shr 24'i32 and 0xff'i32)
+    inc(i, 4)
+
+proc transform(Buffer: pointer, State: var MD5State) = 
+  var
+    myBlock: MD5Block
+  encode(myBlock, cast[cstring](buffer))
+  var a = State[0]
+  var b = State[1]
+  var c = State[2]
+  var d = State[3]
+  FF(a, b, c, d, myBlock[0], 7'i8, 0xD76AA478'i32)
+  FF(d, a, b, c, myBlock[1], 12'i8, 0xE8C7B756'i32)
+  FF(c, d, a, b, myBlock[2], 17'i8, 0x242070DB'i32)
+  FF(b, c, d, a, myBlock[3], 22'i8, 0xC1BDCEEE'i32)
+  FF(a, b, c, d, myBlock[4], 7'i8, 0xF57C0FAF'i32)
+  FF(d, a, b, c, myBlock[5], 12'i8, 0x4787C62A'i32)
+  FF(c, d, a, b, myBlock[6], 17'i8, 0xA8304613'i32)
+  FF(b, c, d, a, myBlock[7], 22'i8, 0xFD469501'i32)
+  FF(a, b, c, d, myBlock[8], 7'i8, 0x698098D8'i32)
+  FF(d, a, b, c, myBlock[9], 12'i8, 0x8B44F7AF'i32)
+  FF(c, d, a, b, myBlock[10], 17'i8, 0xFFFF5BB1'i32)
+  FF(b, c, d, a, myBlock[11], 22'i8, 0x895CD7BE'i32)
+  FF(a, b, c, d, myBlock[12], 7'i8, 0x6B901122'i32)
+  FF(d, a, b, c, myBlock[13], 12'i8, 0xFD987193'i32)
+  FF(c, d, a, b, myBlock[14], 17'i8, 0xA679438E'i32)
+  FF(b, c, d, a, myBlock[15], 22'i8, 0x49B40821'i32)
+  GG(a, b, c, d, myBlock[1], 5'i8, 0xF61E2562'i32)
+  GG(d, a, b, c, myBlock[6], 9'i8, 0xC040B340'i32)
+  GG(c, d, a, b, myBlock[11], 14'i8, 0x265E5A51'i32)
+  GG(b, c, d, a, myBlock[0], 20'i8, 0xE9B6C7AA'i32)
+  GG(a, b, c, d, myBlock[5], 5'i8, 0xD62F105D'i32)
+  GG(d, a, b, c, myBlock[10], 9'i8, 0x02441453'i32)
+  GG(c, d, a, b, myBlock[15], 14'i8, 0xD8A1E681'i32)
+  GG(b, c, d, a, myBlock[4], 20'i8, 0xE7D3FBC8'i32)
+  GG(a, b, c, d, myBlock[9], 5'i8, 0x21E1CDE6'i32)
+  GG(d, a, b, c, myBlock[14], 9'i8, 0xC33707D6'i32)
+  GG(c, d, a, b, myBlock[3], 14'i8, 0xF4D50D87'i32)
+  GG(b, c, d, a, myBlock[8], 20'i8, 0x455A14ED'i32)
+  GG(a, b, c, d, myBlock[13], 5'i8, 0xA9E3E905'i32)
+  GG(d, a, b, c, myBlock[2], 9'i8, 0xFCEFA3F8'i32)
+  GG(c, d, a, b, myBlock[7], 14'i8, 0x676F02D9'i32)
+  GG(b, c, d, a, myBlock[12], 20'i8, 0x8D2A4C8A'i32)
+  HH(a, b, c, d, myBlock[5], 4'i8, 0xFFFA3942'i32)
+  HH(d, a, b, c, myBlock[8], 11'i8, 0x8771F681'i32)
+  HH(c, d, a, b, myBlock[11], 16'i8, 0x6D9D6122'i32)
+  HH(b, c, d, a, myBlock[14], 23'i8, 0xFDE5380C'i32)
+  HH(a, b, c, d, myBlock[1], 4'i8, 0xA4BEEA44'i32)
+  HH(d, a, b, c, myBlock[4], 11'i8, 0x4BDECFA9'i32)
+  HH(c, d, a, b, myBlock[7], 16'i8, 0xF6BB4B60'i32)
+  HH(b, c, d, a, myBlock[10], 23'i8, 0xBEBFBC70'i32)
+  HH(a, b, c, d, myBlock[13], 4'i8, 0x289B7EC6'i32)
+  HH(d, a, b, c, myBlock[0], 11'i8, 0xEAA127FA'i32)
+  HH(c, d, a, b, myBlock[3], 16'i8, 0xD4EF3085'i32)
+  HH(b, c, d, a, myBlock[6], 23'i8, 0x04881D05'i32)
+  HH(a, b, c, d, myBlock[9], 4'i8, 0xD9D4D039'i32)
+  HH(d, a, b, c, myBlock[12], 11'i8, 0xE6DB99E5'i32)
+  HH(c, d, a, b, myBlock[15], 16'i8, 0x1FA27CF8'i32)
+  HH(b, c, d, a, myBlock[2], 23'i8, 0xC4AC5665'i32)
+  II(a, b, c, d, myBlock[0], 6'i8, 0xF4292244'i32)
+  II(d, a, b, c, myBlock[7], 10'i8, 0x432AFF97'i32)
+  II(c, d, a, b, myBlock[14], 15'i8, 0xAB9423A7'i32)
+  II(b, c, d, a, myBlock[5], 21'i8, 0xFC93A039'i32)
+  II(a, b, c, d, myBlock[12], 6'i8, 0x655B59C3'i32)
+  II(d, a, b, c, myBlock[3], 10'i8, 0x8F0CCC92'i32)
+  II(c, d, a, b, myBlock[10], 15'i8, 0xFFEFF47D'i32)
+  II(b, c, d, a, myBlock[1], 21'i8, 0x85845DD1'i32)
+  II(a, b, c, d, myBlock[8], 6'i8, 0x6FA87E4F'i32)
+  II(d, a, b, c, myBlock[15], 10'i8, 0xFE2CE6E0'i32)
+  II(c, d, a, b, myBlock[6], 15'i8, 0xA3014314'i32)
+  II(b, c, d, a, myBlock[13], 21'i8, 0x4E0811A1'i32)
+  II(a, b, c, d, myBlock[4], 6'i8, 0xF7537E82'i32)
+  II(d, a, b, c, myBlock[11], 10'i8, 0xBD3AF235'i32)
+  II(c, d, a, b, myBlock[2], 15'i8, 0x2AD7D2BB'i32)
+  II(b, c, d, a, myBlock[9], 21'i8, 0xEB86D391'i32)
+  State[0] = State[0] +% a
+  State[1] = State[1] +% b
+  State[2] = State[2] +% c
+  State[3] = State[3] +% d
+  
+proc MD5Init*(c: var MD5Context) = 
+  ## initializes a MD5Context  
+  c.State[0] = 0x67452301'i32
+  c.State[1] = 0xEFCDAB89'i32
+  c.State[2] = 0x98BADCFE'i32
+  c.State[3] = 0x10325476'i32
+  c.Count[0] = 0'i32
+  c.Count[1] = 0'i32
+  ZeroMem(addr(c.Buffer), SizeOf(MD5Buffer))
+
+proc MD5Update*(c: var MD5Context, input: cstring, len: int) = 
+  ## updates the MD5Context with the `input` data of length `len`
+  var input = input
+  var Index = (c.Count[0] shr 3) and 0x3F
+  c.Count[0] = c.count[0] +% toU32(len shl 3)
+  if c.Count[0] < (len shl 3): c.Count[1] = c.count[1] +% 1'i32
+  c.Count[1] = c.count[1] +% toU32(len shr 29)
+  var PartLen = 64 - Index
+  if len >= PartLen: 
+    CopyMem(addr(c.Buffer[Index]), Input, PartLen)
+    transform(addr(c.Buffer), c.State)
+    var i = PartLen
+    while i + 63 < len: 
+      Transform(addr(Input[I]), c.State)
+      inc(i, 64)
+    CopyMem(addr(c.Buffer[0]), addr(Input[i]), len-i)
+  else:
+    CopyMem(addr(c.Buffer[Index]), addr(Input[0]), len)
+
+proc MD5Final*(c: var MD5Context, digest: var MD5Digest) = 
+  ## finishes the MD5Context and stores the result in `digest`
+  var
+    Bits: MD5CBits
+    PadLen: int
+  decode(bits, c.Count)
+  var Index = (c.Count[0] shr 3) and 0x3F
+  if Index < 56: PadLen = 56 - Index
+  else: PadLen = 120 - Index
+  MD5Update(c, padding, PadLen)
+  MD5Update(c, cast[cstring](addr(Bits)), 8)
+  decode(digest, c.State)
+  ZeroMem(addr(c), SizeOf(MD5Context))
+
+proc toMD5*(s: string): MD5Digest = 
+  ## computes the MD5Digest value for a string `s`
+  var c: MD5Context
+  MD5Init(c)
+  MD5Update(c, cstring(s), len(s))
+  MD5Final(c, result)
+  
+proc `$`*(D: MD5Digest): string = 
+  ## converts a MD5Digest value into its string representation
+  const digits = "0123456789abcdef"
+  result = ""
+  for i in 0..15: 
+    add(result, Digits[(D[I] shr 4) and 0xF])
+    add(result, Digits[D[I] and 0xF])
+
+proc getMD5*(s: string): string =  
+  ## computes an MD5 value of `s` and returns its string representation
+  var 
+    c: MD5Context
+    d: MD5Digest
+  MD5Init(c)
+  MD5Update(c, cstring(s), len(s))
+  MD5Final(c, d)
+  result = $d
+  
+proc `==`*(D1, D2: MD5Digest): bool =  
+  ## checks if two MD5Digest values are identical
+  for i in 0..15: 
+    if D1[i] != D2[i]: return false
+  return true
+
+when isMainModule:
+  assert(getMD5("Franz jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
+    "a3cca2b2aa1e3b5b3b5aad99a8529074")
+  assert(getMD5("Frank jagt im komplett verwahrlosten Taxi quer durch Bayern") ==
+    "7e716d0e702df0505fc72e2b89467910")
+  assert($toMD5("") == "d41d8cd98f00b204e9800998ecf8427e")
+
+
diff --git a/lib/os.nim b/lib/pure/os.nim
index 20e803ec0..847117d93 100644
--- a/lib/os.nim
+++ b/lib/pure/os.nim
@@ -18,6 +18,15 @@
 import
   strutils, times
 
+when defined(windows):
+  import winlean
+elif defined(posix): 
+  import posix
+else:
+  {.error: "OS module not ported to your operating system!".}
+
+include "system/ansi_c"
+
 # copied from excpt.nim, because I don't want to make this template public
 template newException(exceptn, message: expr): expr =
   block: # open a new scope
@@ -150,200 +159,6 @@ const
     ## The character which separates the base filename from the extension;
     ## for example, the '.' in ``os.nim``.
 
-proc getApplicationDir*(): string {.noSideEffect.}
-  ## Returns the directory of the application's executable.
-
-proc getApplicationFilename*(): string {.noSideEffect.}
-  ## Returns the filename of the application's executable.
-
-proc getCurrentDir*(): string {.noSideEffect.}
-  ## Returns the current working directory.
-
-proc setCurrentDir*(newDir: string) {.inline.}
-  ## Sets the current working directory; `EOS` is raised if
-  ## `newDir` cannot been set.
-
-proc getHomeDir*(): string {.noSideEffect.}
-  ## Returns the home directory of the current user.
-
-proc getConfigDir*(): string {.noSideEffect.}
-  ## Returns the config directory of the current user for applications.
-
-proc expandFilename*(filename: string): string
-  ## Returns the full path of `filename`, raises EOS in case of an error.
-
-proc ExistsFile*(filename: string): bool
-  ## Returns true if the file exists, false otherwise.
-
-proc JoinPath*(head, tail: string): string {.noSideEffect.}
-  ## Joins two directory names to one.
-  ##
-  ## For example on Unix:
-  ##
-  ## ..code-block:: nimrod
-  ##   JoinPath("usr", "lib")
-  ##
-  ## results in:
-  ##
-  ## ..code-block:: nimrod
-  ##   "usr/lib"
-  ##
-  ## If head is the empty string, tail is returned.
-  ## If tail is the empty string, head is returned.
-
-proc `/` * (head, tail: string): string {.noSideEffect.} =
-  ## The same as ``joinPath(head, tail)``
-  return joinPath(head, tail)
-
-proc JoinPath*(parts: openarray[string]): string {.noSideEffect.}
-  ## The same as `JoinPath(head, tail)`, but works with any number
-  ## of directory parts.
-
-proc SplitPath*(path: string, head, tail: var string) {.noSideEffect.}
-  ## Splits a directory into (head, tail), so that
-  ## ``JoinPath(head, tail) == path``.
-  ##
-  ## Example: After ``SplitPath("usr/local/bin", head, tail)``,
-  ## `head` is "usr/local" and `tail` is "bin".
-  ## Example: After ``SplitPath("usr/local/bin/", head, tail)``,
-  ## `head` is "usr/local/bin" and `tail` is "".
-
-proc parentDir*(path: string): string {.noSideEffect.}
-  ## Returns the parent directory of `path`.
-  ##
-  ## This is often the same as the ``head`` result of ``splitPath``.
-  ## If there is no parent, ``path`` is returned.
-  ## Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
-  ## Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
-
-proc `/../` * (head, tail: string): string {.noSideEffect.} =
-  ## The same as ``parentDir(head) / tail``
-  return parentDir(head) / tail
-
-proc UnixToNativePath*(path: string): string {.noSideEffect.}
-  ## Converts an UNIX-like path to a native one.
-  ##
-  ## On an UNIX system this does nothing. Else it converts
-  ## '/', '.', '..' to the appropriate things.
-
-proc SplitFilename*(filename: string, name, extension: var string) {.
-  noSideEffect.}
-  ## Splits a filename into (name, extension), so that
-  ## ``name & extension == filename``.
-  ##
-  ## Example: After ``SplitFilename("usr/local/nimrodc.html", name, ext)``,
-  ## `name` is "usr/local/nimrodc" and `ext` is ".html".
-  ## It the file has no extension, extention is the empty string.
-
-proc extractDir*(path: string): string {.noSideEffect.}
-  ## Extracts the directory of a given path. This is almost the
-  ## same as the `head` result of `splitPath`, except that
-  ## ``extractDir("/usr/lib/") == "/usr/lib/"``.
-
-proc extractFilename*(path: string): string {.noSideEffect.}
-  ## Extracts the filename of a given `path`. This is almost the
-  ## same as the `tail` result of `splitPath`, except that
-  ## ``extractFilename("/usr/lib/") == ""``.
-
-proc extractFileExt*(filename: string): string {.noSideEffect.} =
-  ## Extracts the file extension of a given `filename`. This is the
-  ## same as the `extension` result of `splitFilename`.
-  var dummy: string
-  splitFilename(filename, dummy, result)
-
-proc extractFileTrunk*(filename: string): string {.noSideEffect.} =
-  ## Extracts the file name of a given `filename`. This removes any
-  ## directory information and the file extension.
-  var dummy: string
-  splitFilename(extractFilename(filename), result, dummy)
-
-proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.}
-  ## Compares two paths.
-  ##
-  ## On a case-sensitive filesystem this is done
-  ## case-sensitively otherwise case-insensitively. Returns:
-  ##
-  ## | 0 iff pathA == pathB
-  ## | < 0 iff pathA < pathB
-  ## | > 0 iff pathA > pathB
-
-proc AppendFileExt*(filename, ext: string): string {.noSideEffect.}
-  ## Appends the file extension `ext` to the `filename`, even if
-  ## the `filename` already has an extension.
-  ##
-  ## `Ext` should be given without the leading '.', because some
-  ## filesystems may use a different character.
-  ## (Although I know of none such beast.)
-
-proc ChangeFileExt*(filename, ext: string): string {.noSideEffect.}
-  ## Changes the file extension to `ext`.
-  ##
-  ## If the `filename` has no extension, `ext` will be added.
-  ## If `ext` == "" then the filename will get no extension.
-  ## `Ext` should be given without the leading '.', because some
-  ## filesystems may use a different character. (Although I know
-  ## of none such beast.)
-
-proc executeShellCommand*(command: string): int
-  ## Executes a shell command.
-  ##
-  ## Command has the form 'program args' where args are the command
-  ## line arguments given to program. The proc returns the error code
-  ## of the shell when it has finished. The proc does not return until
-  ## the process has finished. To execute a program without having a
-  ## shell involved, use the `executeProcess` proc of the `osproc`
-  ## module.
-
-# procs operating on a high level for files:
-proc copyFile*(dest, source: string)
-  ## Copies a file from `source` to `dest`. If this fails,
-  ## `EOS` is raised.
-
-proc moveFile*(dest, source: string)
-  ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised.
-
-proc removeFile*(file: string)
-  ## Removes the `file`. If this fails, `EOS` is raised.
-
-proc removeDir*(dir: string)
-  ## Removes the directory `dir` including all subdirectories or files
-  ## in `dir` (recursively). If this fails, `EOS` is raised.
-
-proc createDir*(dir: string)
-  ## Creates the directory `dir`.
-  ##
-  ## The directory may contain several
-  ## subdirectories that do not exist yet. The full path is created. If this
-  ## fails, `EOS` is raised. It does **not** fail if the path already exists
-  ## because for most usages this does not indicate an error.
-
-proc existsDir*(dir: string): bool
-  ## Returns true iff the directory `dir` exists. If `dir` is a file, false
-  ## is returned.
-
-proc getLastModificationTime*(file: string): TTime
-  ## Returns the time of the `file`'s last modification.
-
-proc fileNewer*(a, b: string): bool
-  ## Returns true if the file `a` is newer than file `b`, i.e. if `a`'s
-  ## modification time is later than `b`'s.
-
-# procs dealing with environment variables:
-proc putEnv*(key, val: string)
-  ## Sets the value of the environment variable named `key` to `val`.
-  ## If an error occurs, `EInvalidEnvVar` is raised.
-
-proc getEnv*(key: string): string
-  ## Returns the value of the environment variable named `key`.
-  ##
-  ## If the variable does not exist, "" is returned. To distinguish
-  ## whether a variable exists or it's value is just "", call
-  ## `existsEnv(key)`.
-
-proc existsEnv*(key: string): bool
-  ## Checks whether the environment variable named `key` exists.
-  ## Returns true if it exists, false otherwise.
-
 # procs dealing with command line arguments:
 proc paramCount*(): int
   ## Returns the number of command line arguments given to the
@@ -356,18 +171,6 @@ proc paramStr*(i: int): string
   ## `i` should be in the range `1..paramCount()`, else
   ## the `EOutOfIndex` exception is raised.
 
-when defined(windows):
-  proc GetLastError(): int32 {.importc, stdcall, dynlib: "kernel32".}
-  proc FormatMessageA(dwFlags: int32, lpSource: pointer,
-                      dwMessageId, dwLanguageId: int32,
-                      lpBuffer: pointer, nSize: int32,
-                      Arguments: pointer): int32 {.
-                      importc, stdcall, dynlib: "kernel32".}
-  proc LocalFree(p: pointer) {.importc, stdcall, dynlib: "kernel32".}
-
-var errno {.importc, header: "<errno.h>".}: cint ## error variable
-proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".}
-
 proc OSError*(msg: string = "") {.noinline.} =
   ## raises an EOS exception with the given message ``msg``.
   ## If ``msg == ""``, the operating system's error flag
@@ -387,15 +190,17 @@ proc OSError*(msg: string = "") {.noinline.} =
             LocalFree(msgbuf)
           raise newException(EOS, m)
     if errno != 0'i32:
-      raise newException(EOS, $strerror(errno))
+      raise newException(EOS, $os.strerror(errno))
     else:
       raise newException(EOS, "unknown OS error")
   else:
     raise newException(EOS, msg)
 
-# implementation
-
-proc UnixToNativePath(path: string): string =
+proc UnixToNativePath*(path: string): string {.noSideEffect.} =
+  ## Converts an UNIX-like path to a native one.
+  ##
+  ## On an UNIX system this does nothing. Else it converts
+  ## '/', '.', '..' to the appropriate things.
   when defined(unix):
     result = path
   else:
@@ -436,151 +241,73 @@ proc UnixToNativePath(path: string): string =
         add result, path[i]
         inc(i)
 
-# interface to C library:
-
-const
-  cunder = if defined(pcc): "_" else: ""
-
-type
-  TStat {.importc: "struct " & cunder & "stat",
-          header: "<sys/stat.h>", pure.} = object
-    st_dev: int16
-    st_ino: int16
-    st_mode: int16
-    st_nlink: int16
-    st_uid: int16
-    st_gid: int16
-    st_rdev: int32
-    st_size: int32
-    st_atime: TTime
-    st_mtime: TTime
-    st_ctime: TTime
-
-
-when defined(unix):
-  var
-    EEXIST {.importc: "EEXIST", header: "<errno.h>".}: cint
-
-  proc mkdir(dir: CString, theAccess: cint): cint {.
-    importc: "mkdir", header: "<sys/stat.h>".}
-  proc realpath(name, resolved: CString): CString {.
-    importc: "realpath", header: "<stdlib.h>".}
-  proc getcwd(buf: CString, buflen: cint): CString {.
-    importc: "getcwd", header: "<unistd.h>".}
-  proc chdir(path: CString): cint {.
-    importc: "chdir", header: "<unistd.h>".}
-  proc rmdir(dir: CString): cint {.
-    importc: "rmdir", header: "<unistd.h>".}
-
-  # is in <stdlib.h>:
-  proc cputenv(env: CString): cint {.importc: "putenv", noDecl.}
-
-elif defined(windows):
-  proc GetCurrentDirectoryA(nBufferLength: int32, lpBuffer: cstring): int32 {.
-    importc, dynlib: "kernel32", stdcall.}
-  proc SetCurrentDirectoryA(lpPathName: cstring): int32 {.
-    importc, dynlib: "kernel32", stdcall.}
-  proc CreateDirectoryA(pathName: cstring, security: Pointer): int32 {.
-    importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.}
-  proc RemoveDirectoryA(lpPathName: cstring): int32 {.
-    importc, dynlib: "kernel32", stdcall.}
-  proc SetEnvironmentVariableA(lpName, lpValue: cstring): int32 {.
-    stdcall, dynlib: "kernel32", importc.}
-else:
-  {.error: "os library not ported to your OS. Please help!".}
-
-
-
-when defined(unix):
-  proc free(c: cstring) {.importc: "free", nodecl.}
-    # some C procs return a buffer that has to be freed with free(),
-    # so we define it here
-  proc strlen(str: CString): int {.importc: "strlen", nodecl.}
-
-proc stat(f: CString, res: var TStat): cint {.
-  importc: cunder & "stat", header: "<time.h>".}
-  # stat is of course in ``<sys/stat.h>``, but I include
-  # time.h which is needed for stat() too. stat() needs both time.h and
-  # sys/stat.h.
-
-when defined(windows):
-  proc GetModuleFileNameA(handle: int32, buf: CString, size: int32): int32 {.
-    importc, dynlib: "kernel32", stdcall.}
-
-proc getLastModificationTime(file: string): TTime =
-  var
-    res: TStat
-  discard stat(file, res)
-  return res.st_mtime
-
-proc setCurrentDir(newDir: string) =
-  when defined(Windows):
-    if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
+proc existsFile*(filename: string): bool =
+  ## Returns true if the file exists, false otherwise.
+  when defined(windows):
+    var a = GetFileAttributesA(filename)
+    if a != -1'i32:
+      result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32
   else:
-    if chdir(newDir) != 0'i32: OSError()
-
-when defined(linux) or defined(solaris) or defined(bsd) or defined(aix):
-  proc readlink(link, buf: cstring, size: int): int {.
-    header: "<unistd.h>", cdecl.}
-
-  proc getApplAux(procPath: string): string =
-    result = newString(256)
-    var len = readlink(procPath, result, 256)
-    if len > 256:
-      result = newString(len+1)
-      len = readlink(procPath, result, len)
-    setlen(result, len)
-
-when defined(solaris) or defined(bsd):
-  proc getpid(): int {.importc, header: "<unistd.h>", cdecl.}
-elif defined(macosx):
-  # a really hacky solution: since we like to include 2 headers we have to
-  # define two procs which in reality are the same
-  proc getExecPath1(c: cstring, size: var int32) {.
-    importc: "_NSGetExecutablePath", header: "<sys/param.h>".}
-  proc getExecPath2(c: cstring, size: var int32): bool {.
-    importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".}
+    var res: TStat
+    return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
 
-proc getApplicationFilename(): string =
-  # Linux: /proc/<pid>/exe
-  # Solaris:
-  # /proc/<pid>/object/a.out (filename only)
-  # /proc/<pid>/path/a.out (complete pathname)
-  # *BSD (and maybe Darwin too):
-  # /proc/<pid>/file
+proc existsDir*(dir: string): bool =
+  ## Returns true iff the directory `dir` exists. If `dir` is a file, false
+  ## is returned.
   when defined(windows):
-    result = newString(256)
-    var len = getModuleFileNameA(0, result, 256)
-    setlen(result, int(len))
-  elif defined(linux) or defined(aix):
-    result = getApplAux("/proc/self/exe")
-  elif defined(solaris):
-    result = getApplAux("/proc/" & $getpid() & "/path/a.out")
-  elif defined(bsd):
-    result = getApplAux("/proc/" & $getpid() & "/file")
-  elif defined(macosx):
-    var size: int32
-    getExecPath1(nil, size)
-    result = newString(int(size))
-    if getExecPath2(result, size):
-      result = "" # error!
+    var a = GetFileAttributesA(dir)
+    if a != -1'i32:
+      result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
   else:
-    # little heuristic that may work on other POSIX-like systems:
-    result = getEnv("_")
-    if len(result) == 0:
-      result = ParamStr(0) # POSIX guaranties that this contains the executable
-                           # as it has been executed by the calling process
-      if len(result) > 0 and result[0] != DirSep: # not an absolute path?
-        # iterate over any path in the $PATH environment variable
-        for p in split(getEnv("PATH"), {PathSep}):
-          var x = joinPath(p, result)
-          if ExistsFile(x): return x
+    var res: TStat
+    return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
 
-proc getApplicationDir(): string =
-  var tail: string
-  splitPath(getApplicationFilename(), result, tail)
+proc getLastModificationTime*(file: string): TTime =
+  ## Returns the `file`'s last modification time.
+  when defined(posix):
+    var res: TStat
+    if stat(file, res) < 0'i32: OSError()
+    return res.st_mtime
+  else:
+    var f: TWIN32_Find_Data
+    var h = findfirstFileA(file, f)
+    if h == -1'i32: OSError()
+    result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime))
+    findclose(h)
+
+proc getLastAccessTime*(file: string): TTime =
+  ## Returns the `file`'s last read or write access time.
+  when defined(posix):
+    var res: TStat
+    if stat(file, res) < 0'i32: OSError()
+    return res.st_atime
+  else:
+    var f: TWIN32_Find_Data
+    var h = findfirstFileA(file, f)
+    if h == -1'i32: OSError()
+    result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime))
+    findclose(h)
+
+proc getCreationTime*(file: string): TTime = 
+  ## Returns the `file`'s creation time.
+  when defined(posix):
+    var res: TStat
+    if stat(file, res) < 0'i32: OSError()
+    return res.st_ctime
+  else:
+    var f: TWIN32_Find_Data
+    var h = findfirstFileA(file, f)
+    if h == -1'i32: OSError()
+    result = winTimeToUnixTime(rdFileTime(f.ftCreationTime))
+    findclose(h)
 
-proc getCurrentDir(): string =
+proc fileNewer*(a, b: string): bool =
+  ## Returns true if the file `a` is newer than file `b`, i.e. if `a`'s
+  ## modification time is later than `b`'s.
+  result = getLastModificationTime(a) - getLastModificationTime(b) > 0
+
+proc getCurrentDir*(): string =
+  ## Returns the current working directory.
   const bufsize = 512 # should be enough
   result = newString(bufsize)
   when defined(windows):
@@ -589,11 +316,33 @@ proc getCurrentDir(): string =
     setLen(result, L)
   else:
     if getcwd(result, bufsize) != nil:
-      setlen(result, strlen(result))
+      setlen(result, c_strlen(result))
     else:
       OSError()
 
-proc JoinPath(head, tail: string): string =
+proc setCurrentDir*(newDir: string) {.inline.} =
+  ## Sets the current working directory; `EOS` is raised if
+  ## `newDir` cannot been set.
+  when defined(Windows):
+    if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
+  else:
+    if chdir(newDir) != 0'i32: OSError()
+
+proc JoinPath*(head, tail: string): string {.noSideEffect.} =
+  ## Joins two directory names to one.
+  ##
+  ## For example on Unix:
+  ##
+  ## ..code-block:: nimrod
+  ##   JoinPath("usr", "lib")
+  ##
+  ## results in:
+  ##
+  ## ..code-block:: nimrod
+  ##   "usr/lib"
+  ##
+  ## If head is the empty string, tail is returned.
+  ## If tail is the empty string, head is returned.
   if len(head) == 0:
     result = tail
   elif head[len(head)-1] in {DirSep, AltSep}:
@@ -607,41 +356,67 @@ proc JoinPath(head, tail: string): string =
     else:
       result = head & DirSep & tail
 
-proc JoinPath(parts: openarray[string]): string =
+proc JoinPath*(parts: openarray[string]): string {.noSideEffect.} =
+  ## The same as `JoinPath(head, tail)`, but works with any number
+  ## of directory parts.
   result = parts[0]
   for i in 1..high(parts):
     result = JoinPath(result, parts[i])
 
-proc parentDir(path: string): string =
+proc `/` * (head, tail: string): string {.noSideEffect.} =
+  ## The same as ``joinPath(head, tail)``
+  return joinPath(head, tail)
+
+proc SplitPath*(path: string, head, tail: var string) {.noSideEffect.} =
+  ## Splits a directory into (head, tail), so that
+  ## ``JoinPath(head, tail) == path``.
+  ##
+  ## Example: After ``SplitPath("usr/local/bin", head, tail)``,
+  ## `head` is "usr/local" and `tail` is "bin".
+  ## Example: After ``SplitPath("usr/local/bin/", head, tail)``,
+  ## `head` is "usr/local/bin" and `tail` is "".
   var
     sepPos = -1
-    q = 1
-  if path[len(path)-1] in {dirsep, altsep}:
-    q = 2
-  for i in countdown(len(path)-q, 0):
+  for i in countdown(len(path)-1, 0):
     if path[i] in {dirsep, altsep}:
       sepPos = i
       break
   if sepPos >= 0:
-    result = copy(path, 0, sepPos-1)
+    head = copy(path, 0, sepPos-1)
+    tail = copy(path, sepPos+1)
   else:
-    result = path
+    head = ""
+    tail = path # make a string copy here
 
-proc SplitPath(path: string, head, tail: var string) =
+proc parentDir*(path: string): string {.noSideEffect.} =
+  ## Returns the parent directory of `path`.
+  ##
+  ## This is often the same as the ``head`` result of ``splitPath``.
+  ## If there is no parent, ``path`` is returned.
+  ## Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
+  ## Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
   var
     sepPos = -1
-  for i in countdown(len(path)-1, 0):
+    q = 1
+  if path[len(path)-1] in {dirsep, altsep}:
+    q = 2
+  for i in countdown(len(path)-q, 0):
     if path[i] in {dirsep, altsep}:
       sepPos = i
       break
   if sepPos >= 0:
-    head = copy(path, 0, sepPos-1)
-    tail = copy(path, sepPos+1)
+    result = copy(path, 0, sepPos-1)
   else:
-    head = ""
-    tail = path # make a string copy here
+    result = path
+
+proc `/../` * (head, tail: string): string {.noSideEffect.} =
+  ## The same as ``parentDir(head) / tail``
+  return parentDir(head) / tail
+
+proc normExt(ext: string): string =
+  if ext == "" or ext[0] == extSep: result = ext # no copy needed here
+  else: result = extSep & ext
 
-# helper:
 proc searchExtPos(s: string): int =
   result = -1
   for i in countdown(len(s)-1, 0):
@@ -651,7 +426,48 @@ proc searchExtPos(s: string): int =
     elif s[i] in {dirsep, altsep}:
       break # do not skip over path
 
-proc SplitFilename(filename: string, name, extension: var string) =
+proc extractDir*(path: string): string {.noSideEffect.} =
+  ## Extracts the directory of a given path. This is almost the
+  ## same as the `head` result of `splitPath`, except that
+  ## ``extractDir("/usr/lib/") == "/usr/lib/"``.
+  if path.len == 0 or path[path.len-1] in {dirSep, altSep}:
+    result = path
+  else:
+    var tail: string
+    splitPath(path, result, tail)
+
+proc extractFilename*(path: string): string {.noSideEffect.} =
+  ## Extracts the filename of a given `path`. This is almost the
+  ## same as the `tail` result of `splitPath`, except that
+  ## ``extractFilename("/usr/lib/") == ""``.
+  if path.len == 0 or path[path.len-1] in {dirSep, altSep}:
+    result = ""
+  else:
+    var head: string
+    splitPath(path, head, result)
+
+proc expandFilename*(filename: string): string =
+  ## Returns the full path of `filename`, raises EOS in case of an error.
+  when defined(windows):
+    var unused: cstring
+    result = newString(3072)
+    var L = GetFullPathNameA(filename, 3072'i32, result, unused)
+    if L <= 0'i32 or L >= 3072'i32: OSError()
+    setLen(result, L)
+  else:
+    var res = realpath(filename, nil)
+    if res == nil: OSError()
+    result = $res
+    c_free(res)
+
+proc SplitFilename*(filename: string, name, extension: var string) {.
+  noSideEffect.} = 
+  ## Splits a filename into (name, extension), so that
+  ## ``name & extension == filename``.
+  ##
+  ## Example: After ``SplitFilename("usr/local/nimrodc.html", name, ext)``,
+  ## `name` is "usr/local/nimrodc" and `ext` is ".html".
+  ## It the file has no extension, extention is the empty string.
   var extPos = searchExtPos(filename)
   if extPos >= 0:
     name = copy(filename, 0, extPos-1)
@@ -660,85 +476,54 @@ proc SplitFilename(filename: string, name, extension: var string) =
     name = filename # make a string copy here
     extension = ""
 
-proc normExt(ext: string): string =
-  if ext == "" or ext[0] == extSep: result = ext # no copy needed here
-  else: result = extSep & ext
+proc extractFileExt*(filename: string): string {.noSideEffect.} =
+  ## Extracts the file extension of a given `filename`. This is the
+  ## same as the `extension` result of `splitFilename`.
+  var dummy: string
+  splitFilename(filename, dummy, result)
+
+proc extractFileTrunk*(filename: string): string {.noSideEffect.} =
+  ## Extracts the file name of a given `filename`. This removes any
+  ## directory information and the file extension.
+  var dummy: string
+  splitFilename(extractFilename(filename), result, dummy)
 
-proc ChangeFileExt(filename, ext: string): string =
+proc ChangeFileExt*(filename, ext: string): string {.noSideEffect.} =
+  ## Changes the file extension to `ext`.
+  ##
+  ## If the `filename` has no extension, `ext` will be added.
+  ## If `ext` == "" then any extension is removed.
+  ## `Ext` should be given without the leading '.', because some
+  ## filesystems may use a different character. (Although I know
+  ## of none such beast.)
   var extPos = searchExtPos(filename)
   if extPos < 0: result = filename & normExt(ext)
   else: result = copy(filename, 0, extPos-1) & normExt(ext)
 
-proc AppendFileExt(filename, ext: string): string =
+proc AppendFileExt*(filename, ext: string): string {.noSideEffect.} =
+  ## Appends the file extension `ext` to `filename`, unless
+  ## `filename` already has an extension.
+  ##
+  ## `Ext` should be given without the leading '.', because some
+  ## filesystems may use a different character.
+  ## (Although I know of none such beast.)
   var extPos = searchExtPos(filename)
   if extPos < 0: result = filename & normExt(ext)
   else: result = filename #make a string copy here
 
-# some more C things:
-
-proc csystem(cmd: CString): cint {.importc: "system", noDecl.}
-  # is in <stdlib.h>!
-
-proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
-
-when defined(windows):
-  const
-    FILE_ATTRIBUTE_DIRECTORY = 16
-    MAX_PATH = 260
-  type
-    HANDLE = int
-    FILETIME {.pure.} = object
-      dwLowDateTime: int32
-      dwHighDateTime: int32
-    TWIN32_FIND_DATA {.pure.} = object
-      dwFileAttributes: int32
-      ftCreationTime: FILETIME
-      ftLastAccessTime: FILETIME
-      ftLastWriteTime: FILETIME
-      nFileSizeHigh: int32
-      nFileSizeLow: int32
-      dwReserved0: int32
-      dwReserved1: int32
-      cFileName: array[0..(MAX_PATH) - 1, char]
-      cAlternateFileName: array[0..13, char]
-  proc FindFirstFileA(lpFileName: cstring,
-                      lpFindFileData: var TWIN32_FIND_DATA): HANDLE {.
-      stdcall, dynlib: "kernel32", importc: "FindFirstFileA".}
-  proc FindNextFileA(hFindFile: HANDLE,
-                     lpFindFileData: var TWIN32_FIND_DATA): int32 {.
-      stdcall, dynlib: "kernel32", importc: "FindNextFileA".}
-  proc FindClose(hFindFile: HANDLE) {.stdcall, dynlib: "kernel32",
-    importc: "FindClose".}
-
-  proc GetFullPathNameA(lpFileName: cstring, nBufferLength: int32,
-                        lpBuffer: cstring, lpFilePart: var cstring): int32 {.
-                        stdcall, dynlib: "kernel32", importc.}
-  proc GetFileAttributesA(lpFileName: cstring): int32 {.
-                          stdcall, dynlib: "kernel32", importc.}
-
-else:
-  type
-    TDIR {.importc: "DIR", header: "<dirent.h>", pure.} = object
-    TDirent {.importc: "struct dirent", header: "<dirent.h>", pure.} = object
-      d_name: array [0..255, char]
-
-  proc opendir(dir: cstring): ptr TDIR {.importc, header: "<dirent.h>".}
-  proc closedir(dir: ptr TDIR) {.importc, header: "<dirent.h>".}
-  proc readdir(dir: ptr TDIR): ptr TDirent {.importc, header: "<dirent.h>".}
-
-  type
-    TGlob {.importc: "glob_t", header: "<glob.h>", final, pure.} = object
-      gl_pathc: int     # count of paths matched by pattern
-      gl_pathv: cstringArray # list of matched path names
-      gl_offs: int      # slots to reserve at beginning of gl_pathv
-    PGlob = ptr TGlob
-
-  proc glob(pattern: cstring, flags: cint, errfunc: pointer,
-            pglob: PGlob): cint {.
-    importc: "glob", header: "<glob.h>".}
-
-  proc globfree(pglob: PGlob) {.
-    importc: "globfree", header: "<glob.h>".}
+proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.} =
+  ## Compares two paths.
+  ##
+  ## On a case-sensitive filesystem this is done
+  ## case-sensitively otherwise case-insensitively. Returns:
+  ##
+  ## | 0 iff pathA == pathB
+  ## | < 0 iff pathA < pathB
+  ## | > 0 iff pathA > pathB
+  if FileSystemCaseSensitive:
+    result = cmp(pathA, pathB)
+  else:
+    result = cmpIgnoreCase(pathA, pathB)
 
 proc sameFile*(path1, path2: string): bool =
   ## Returns True if both pathname arguments refer to the same file or
@@ -794,20 +579,13 @@ proc sameFileContent*(path1, path2: string): bool =
   closeFile(a)
   closeFile(b)
 
-# Ansi C has these:
-proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
-proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
-
-when defined(Windows):
-  proc CopyFileA(lpExistingFileName, lpNewFileName: CString,
-                 bFailIfExists: cint): cint {.
-    importc, stdcall, dynlib: "kernel32".}
-  proc copyFile(dest, source: string) =
+proc copyFile*(dest, source: string) =
+  ## Copies a file from `source` to `dest`. If this fails,
+  ## `EOS` is raised.
+  when defined(Windows):
     if CopyFileA(source, dest, 0'i32) == 0'i32: OSError()
-
-else:
-  # generic version of copyFile which works for any platform:
-  proc copyFile(dest, source: string) =
+  else:
+    # generic version of copyFile which works for any platform:
     const
       bufSize = 8192 # 8K buffer
     var
@@ -828,32 +606,23 @@ else:
     closeFile(s)
     closeFile(d)
 
-proc moveFile(dest, source: string) =
+proc moveFile*(dest, source: string) =
+  ## Moves a file from `source` to `dest`. If this fails, `EOS` is raised.
   if crename(source, dest) != 0'i32: OSError()
 
-proc removeFile(file: string) =
+proc removeFile*(file: string) =
+  ## Removes the `file`. If this fails, `EOS` is raised.
   if cremove(file) != 0'i32: OSError()
 
-proc removeDir(dir: string) =
-  when defined(windows):
-    if RemoveDirectoryA(dir) == 0'i32: OSError()
-  else:
-    if rmdir(dir) != 0'i32: OSError()
-
-proc rawCreateDir(dir: string) =
-  when defined(unix):
-    if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST:
-      OSError()
-  else:
-    if CreateDirectoryA(dir, nil) == 0'i32 and GetLastError() != 183'i32:
-      OSError()
-
-proc createDir(dir: string) =
-  for i in 1.. dir.len-1:
-    if dir[i] in {dirsep, altsep}: rawCreateDir(copy(dir, 0, i-1))
-  rawCreateDir(dir)
-
-proc executeShellCommand(command: string): int =
+proc executeShellCommand*(command: string): int =
+  ## Executes a shell command.
+  ##
+  ## Command has the form 'program args' where args are the command
+  ## line arguments given to program. The proc returns the error code
+  ## of the shell when it has finished. The proc does not return until
+  ## the process has finished. To execute a program without having a
+  ## shell involved, use the `executeProcess` proc of the `osproc`
+  ## module.
   result = csystem(command)
 
 var
@@ -863,12 +632,8 @@ var
 when defined(windows):
   # because we support Windows GUI applications, things get really
   # messy here...
-  proc GetEnvironmentStringsA(): cstring {.
-    stdcall, dynlib: "kernel32", importc.}
-  proc FreeEnvironmentStringsA(para1: cstring): int32 {.
-    stdcall, dynlib: "kernel32", importc.}
-
-  proc strEnd(cstr: CString, c = 0): CString {.importc: "strchr", nodecl.}
+  proc strEnd(cstr: CString, c = 0'i32): CString {.
+    importc: "strchr", header: "<string.h>".}
 
   proc getEnvVarsC() =
     if not envComputed:
@@ -905,7 +670,12 @@ proc findEnvVar(key: string): int =
     if startsWith(environment[i], temp): return i
   return -1
 
-proc getEnv(key: string): string =
+proc getEnv*(key: string): string =
+  ## Returns the value of the environment variable named `key`.
+  ##
+  ## If the variable does not exist, "" is returned. To distinguish
+  ## whether a variable exists or it's value is just "", call
+  ## `existsEnv(key)`.
   var i = findEnvVar(key)
   if i >= 0:
     return copy(environment[i], find(environment[i], '=')+1)
@@ -914,19 +684,16 @@ proc getEnv(key: string): string =
     if env == nil: return ""
     result = $env
 
-proc existsEnv(key: string): bool =
+proc existsEnv*(key: string): bool =
+  ## Checks whether the environment variable named `key` exists.
+  ## Returns true if it exists, false otherwise.
   if cgetenv(key) != nil: return true
   else: return findEnvVar(key) >= 0
 
-iterator iterOverEnvironment*(): tuple[key, value: string] =
-  ## Iterate over all environments varialbes. In the first component of the
-  ## tuple is the name of the current variable stored, in the second its value.
-  getEnvVarsC()
-  for i in 0..high(environment):
-    var p = find(environment[i], '=')
-    yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
+proc putEnv*(key, val: string) =
+  ## Sets the value of the environment variable named `key` to `val`.
+  ## If an error occurs, `EInvalidEnvVar` is raised.
 
-proc putEnv(key, val: string) =
   # Note: by storing the string in the environment sequence,
   # we gurantee that we don't free the memory before the program
   # ends (this is needed for POSIX compliance). It is also needed so that
@@ -944,6 +711,14 @@ proc putEnv(key, val: string) =
     if SetEnvironmentVariableA(key, val) == 0'i32:
       OSError()
 
+iterator iterOverEnvironment*(): tuple[key, value: string] =
+  ## Iterate over all environments varialbes. In the first component of the
+  ## tuple is the name of the current variable stored, in the second its value.
+  getEnvVarsC()
+  for i in 0..high(environment):
+    var p = find(environment[i], '=')
+    yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
+
 iterator walkFiles*(pattern: string): string =
   ## Iterate over all the files that match the `pattern`.
   ##
@@ -981,11 +756,6 @@ type
     pcDirectory,          ## path refers to a directory
     pcLinkToDirectory     ## path refers to a symbolic link to a directory
 
-when defined(posix):
-  proc S_ISDIR(m: int16): bool {.importc, header: "<sys/stat.h>".}
-  proc S_ISLNK(m: int16): bool {.importc, header: "<sys/stat.h>".}
-  proc S_ISREG(m: int16): bool {.importc, header: "<sys/stat.h>".}
-
 iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
   ## walks over the directory `dir` and yields for each directory or file in
   ## `dir`. The component type and full path for each item is returned.
@@ -1014,7 +784,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
       while true:
         var k = pcFile
         if f.cFilename[0] != '.':
-          if (int(f.dwFileAttributes) and FILE_ATTRIBUTE_DIRECTORY) != 0:
+          if (f.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) != 0'i32:
             k = pcDirectory
           yield (k, dir / extractFilename($f.cFilename))
         if findnextFileA(h, f) == 0'i32: break
@@ -1034,59 +804,41 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
           if S_ISDIR(s.st_mode): k = pcDirectory
           if S_ISLNK(s.st_mode): k = succ(k)
           yield (k, y)
-      closeDir(d)
-
-proc ExistsFile(filename: string): bool =
-  when defined(windows):
-    var a = GetFileAttributesA(filename)
-    if a != -1:
-      result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0
-  else:
-    var res: TStat
-    return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
+      discard closeDir(d)
 
-proc existsDir(dir: string): bool =
+proc rawRemoveDir(dir: string) = 
   when defined(windows):
-    var a = GetFileAttributesA(dir)
-    if a != -1:
-      result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0
-  else:
-    var res: TStat
-    return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
-
-proc cmpPaths(pathA, pathB: string): int =
-  if FileSystemCaseSensitive:
-    result = cmp(pathA, pathB)
+    if RemoveDirectoryA(dir) == 0'i32: OSError()
   else:
-    result = cmpIgnoreCase(pathA, pathB)
+    if rmdir(dir) != 0'i32: OSError()
 
-proc extractDir(path: string): string =
-  if path.len == 0 or path[path.len-1] in {dirSep, altSep}:
-    result = path
-  else:
-    var tail: string
-    splitPath(path, result, tail)
+proc removeDir*(dir: string) =
+  ## Removes the directory `dir` including all subdirectories or files
+  ## in `dir` (recursively). If this fails, `EOS` is raised.
+  for kind, path in walkDir(dir): 
+    case kind
+    of pcFile, pcLinkToFile, pcLinkToDirectory: removeFile(path)
+    of pcDirectory: removeDir(dir)
+  rawRemoveDir(dir)
 
-proc extractFilename(path: string): string =
-  if path.len == 0 or path[path.len-1] in {dirSep, altSep}:
-    result = ""
+proc rawCreateDir(dir: string) =
+  when defined(unix):
+    if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST:
+      OSError()
   else:
-    var head: string
-    splitPath(path, head, result)
+    if CreateDirectoryA(dir, nil) == 0'i32 and GetLastError() != 183'i32:
+      OSError()
 
-proc expandFilename(filename: string): string =
-  # returns the full path of 'filename'; "" on error
-  when defined(windows):
-    var unused: cstring
-    result = newString(3072)
-    var L = GetFullPathNameA(filename, 3072'i32, result, unused)
-    if L <= 0'i32 or L >= 3072'i32: OSError()
-    setLen(result, L)
-  else:
-    var res = realpath(filename, nil)
-    if res == nil: OSError()
-    result = $res
-    free(res)
+proc createDir*(dir: string) =
+  ## Creates the directory `dir`.
+  ##
+  ## The directory may contain several subdirectories that do not exist yet.
+  ## The full path is created. If this fails, `EOS` is raised. It does **not**
+  ## fail if the path already exists because for most usages this does not 
+  ## indicate an error.
+  for i in 1.. dir.len-1:
+    if dir[i] in {dirsep, altsep}: rawCreateDir(copy(dir, 0, i-1))
+  rawCreateDir(dir)
 
 proc parseCmdLine*(c: string): seq[string] =
   ## Splits a command line into several components; components are separated by
@@ -1094,8 +846,9 @@ proc parseCmdLine*(c: string): seq[string] =
   ## This proc is only occassionally useful, better use the `parseopt` module.
   result = @[]
   var i = 0
+  var a = ""
   while c[i] != '\0':
-    var a = ""
+    setLen(a, 0)
     while c[i] >= '\1' and c[i] <= ' ': inc(i) # skip whitespace
     case c[i]
     of '\'', '\"':
@@ -1111,17 +864,107 @@ proc parseCmdLine*(c: string): seq[string] =
         inc(i)
     add(result, a)
 
-when defined(windows):
-  proc GetHomeDir(): string = return getEnv("USERPROFILE") & "\\"
-  proc GetConfigDir(): string = return getEnv("APPDATA") & "\\"
+type
+  TFilePermission* = enum  ## file access permission; modelled after UNIX
+    fpUserExec,            ## execute access for the file owner
+    fpUserWrite,           ## write access for the file owner
+    fpUserRead,            ## read access for the file owner
+    fpGroupExec,           ## execute access for the group
+    fpGroupWrite,          ## write access for the group
+    fpGroupRead,           ## read access for the group
+    fpOthersExec,          ## execute access for others
+    fpOthersWrite,         ## write access for others
+    fpOthersRead           ## read access for others
+
+proc getFilePermissions*(filename: string): set[TFilePermission] =
+  ## retrives file permissions for `filename`. `OSError` is raised in case of
+  ## an error. On Windows, only the ``readonly`` flag is checked, every other
+  ## permission is available in any case.
+  when defined(posix):
+    var a: TStat
+    if stat(filename, a) < 0'i32: OSError()
+    result = {}
+    if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead)
+    if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite)
+    if (a.st_mode and S_IXUSR) != 0'i32: result.incl(fpUserExec)
+
+    if (a.st_mode and S_IRGRP) != 0'i32: result.incl(fpGroupRead)
+    if (a.st_mode and S_IWGRP) != 0'i32: result.incl(fpGroupWrite)
+    if (a.st_mode and S_IXGRP) != 0'i32: result.incl(fpGroupExec)
+
+    if (a.st_mode and S_IROTH) != 0'i32: result.incl(fpOthersRead)
+    if (a.st_mode and S_IWOTH) != 0'i32: result.incl(fpOthersWrite)
+    if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec)
+  else:
+    var res = GetFileAttributesA(filename)
+    if res == -1'i32: OSError()
+    if (res and FILE_ATTRIBUTE_READONLY) != 0'i32:
+      result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, 
+                fpOthersExec, fpOthersRead}
+    else:
+      result = {fpUserExec..fpOthersRead}
+  
+proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) =
+  ## sets the file permissions for `filename`. `OSError` is raised in case of
+  ## an error. On Windows, only the ``readonly`` flag is changed, depending on
+  ## ``fpUserWrite``.
+  when defined(posix):
+    var p = 0'i32
+    if fpUserRead in permissions: p = p or S_IRUSR
+    if fpUserWrite in permissions: p = p or S_IWUSR
+    if fpUserExec in permissions: p = p or S_IXUSR
+    
+    if fpGroupRead in permissions: p = p or S_IRGRP
+    if fpGroupWrite in permissions: p = p or S_IWGRP
+    if fpGroupExec in permissions: p = p or S_IXGRP
+    
+    if fpOthersRead in permissions: p = p or S_IROTH
+    if fpOthersWrite in permissions: p = p or S_IWOTH
+    if fpOthersExec in permissions: p = p or S_IXOTH
+    
+    if chmod(filename, p) != 0: OSError()
+  else:
+    var res = GetFileAttributesA(filename)
+    if res == -1'i32: OSError()
+    if fpUserWrite in permissions: 
+      res = res and not FILE_ATTRIBUTE_READONLY
+    else:
+      res = res or FILE_ATTRIBUTE_READONLY
+    if SetFileAttributesA(filename, res) != 0'i32: 
+      OSError()
+  
+proc inclFilePermissions*(filename: string, 
+                          permissions: set[TFilePermission]) =
+  ## a convenience procedure for: 
+  ##
+  ## .. code-block:: nimrod
+  ##   setFilePermissions(filename, getFilePermissions(filename)+permissions)
+  setFilePermissions(filename, getFilePermissions(filename)+permissions)
 
+proc exclFilePermissions*(filename: string, 
+                          permissions: set[TFilePermission]) =
+  ## a convenience procedure for: 
+  ##
+  ## .. code-block:: nimrod
+  ##   setFilePermissions(filename, getFilePermissions(filename)-permissions)
+  setFilePermissions(filename, getFilePermissions(filename)-permissions)
+
+proc getHomeDir*(): string =
+  ## Returns the home directory of the current user.
+  when defined(windows): return getEnv("USERPROFILE") & "\\"
+  else: return getEnv("HOME") & "/"
+
+proc getConfigDir*(): string {.noSideEffect.} =
+  ## Returns the config directory of the current user for applications.
+  when defined(windows): return getEnv("APPDATA") & "\\"
+  else: return getEnv("HOME") & "/.config/"
+
+when defined(windows):
   # Since we support GUI applications with Nimrod, we sometimes generate
   # a WinMain entry proc. But a WinMain proc has no access to the parsed
   # command line arguments. The way to get them differs. Thus we parse them
   # ourselves. This has the additional benefit that the program's behaviour
   # is always the same -- independent of the used C compiler.
-  proc GetCommandLineA(): CString {.importc, stdcall, dynlib: "kernel32".}
-
   var
     ownArgv: seq[string]
 
@@ -1134,9 +977,6 @@ when defined(windows):
     result = ownArgv.len-1
 
 else:
-  proc GetHomeDir(): string = return getEnv("HOME") & "/"
-  proc GetConfigDir(): string = return getEnv("HOME") & "/.config/"
-
   var
     cmdCount {.importc: "cmdCount".}: cint
     cmdLine {.importc: "cmdLine".}: cstringArray
@@ -1147,7 +987,63 @@ else:
 
   proc paramCount(): int = return cmdCount-1
 
-proc fileNewer(a, b: string): bool =
-  result = getLastModificationTime(a) - getLastModificationTime(b) > 0
+when defined(linux) or defined(solaris) or defined(bsd) or defined(aix):
+  proc getApplAux(procPath: string): string =
+    result = newString(256)
+    var len = readlink(procPath, result, 256)
+    if len > 256:
+      result = newString(len+1)
+      len = readlink(procPath, result, len)
+    setlen(result, len)
+
+when defined(macosx):
+  # a really hacky solution: since we like to include 2 headers we have to
+  # define two procs which in reality are the same
+  proc getExecPath1(c: cstring, size: var int32) {.
+    importc: "_NSGetExecutablePath", header: "<sys/param.h>".}
+  proc getExecPath2(c: cstring, size: var int32): bool {.
+    importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".}
+
+proc getApplicationFilename*(): string =
+  ## Returns the filename of the application's executable.
+
+  # Linux: /proc/<pid>/exe
+  # Solaris:
+  # /proc/<pid>/object/a.out (filename only)
+  # /proc/<pid>/path/a.out (complete pathname)
+  # *BSD (and maybe Darwin too):
+  # /proc/<pid>/file
+  when defined(windows):
+    result = newString(256)
+    var len = getModuleFileNameA(0, result, 256)
+    setlen(result, int(len))
+  elif defined(linux) or defined(aix):
+    result = getApplAux("/proc/self/exe")
+  elif defined(solaris):
+    result = getApplAux("/proc/" & $getpid() & "/path/a.out")
+  elif defined(bsd):
+    result = getApplAux("/proc/" & $getpid() & "/file")
+  elif defined(macosx):
+    var size: int32
+    getExecPath1(nil, size)
+    result = newString(int(size))
+    if getExecPath2(result, size):
+      result = "" # error!
+  else:
+    # little heuristic that may work on other POSIX-like systems:
+    result = getEnv("_")
+    if len(result) == 0:
+      result = ParamStr(0) # POSIX guaranties that this contains the executable
+                           # as it has been executed by the calling process
+      if len(result) > 0 and result[0] != DirSep: # not an absolute path?
+        # iterate over any path in the $PATH environment variable
+        for p in split(getEnv("PATH"), {PathSep}):
+          var x = joinPath(p, result)
+          if ExistsFile(x): return x
+
+proc getApplicationDir*(): string =
+  ## Returns the directory of the application's executable.
+  var tail: string
+  splitPath(getApplicationFilename(), result, tail)
 
 {.pop.}
diff --git a/lib/osproc.nim b/lib/pure/osproc.nim
index 205460614..205460614 100644
--- a/lib/osproc.nim
+++ b/lib/pure/osproc.nim
diff --git a/lib/parsecfg.nim b/lib/pure/parsecfg.nim
index 29ba8b4ad..5704f591c 100644
--- a/lib/parsecfg.nim
+++ b/lib/pure/parsecfg.nim
@@ -198,6 +198,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) =
     inc(pos, 2)               # skip ""
                               # skip leading newline:
     pos = HandleCRLF(c, pos)
+    buf = c.buf
     while true: 
       case buf[pos]
       of '\"': 
@@ -206,6 +207,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) =
         Inc(pos)
       of '\c', '\L': 
         pos = HandleCRLF(c, pos)
+        buf = c.buf
         add(tok.literal, nl)
       of lexbase.EndOfFile: 
         tok.kind = tkInvalid
@@ -254,6 +256,7 @@ proc skip(c: var TCfgParser) =
       while not (buf[pos] in {'\c', '\L', lexbase.EndOfFile}): inc(pos)
     of '\c', '\L': 
       pos = HandleCRLF(c, pos)
+      buf = c.buf
     else: 
       break                   # EndOfFile also leaves the loop
   c.bufpos = pos
diff --git a/lib/parsecsv.nim b/lib/pure/parsecsv.nim
index 7665c8287..5970f2090 100644
--- a/lib/parsecsv.nim
+++ b/lib/pure/parsecsv.nim
@@ -103,9 +103,11 @@ proc parseField(my: var TCsvParser, a: var string) =
         case c
         of '\c': 
           pos = handleCR(my, pos)
+          buf = my.buf
           add(a, "\n")
         of '\l': 
           pos = handleLF(my, pos)
+          buf = my.buf
           add(a, "\n")
         else:
           add(a, c)
diff --git a/lib/parseopt.nim b/lib/pure/parseopt.nim
index 12060ba70..12060ba70 100644
--- a/lib/parseopt.nim
+++ b/lib/pure/parseopt.nim
diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim
new file mode 100644
index 000000000..112e79a09
--- /dev/null
+++ b/lib/pure/parsesql.nim
@@ -0,0 +1,1333 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2009 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## The ``parsesql`` module implements a high performance SQL file 
+## parser. It parses PostgreSQL syntax and the SQL ANSI standard.
+
+import 
+  hashes, strutils, lexbase, streams
+
+# ------------------- scanner -------------------------------------------------
+
+type
+  TTokKind = enum       ## enumeration of all SQL tokens
+    tkInvalid,          ## invalid token
+    tkEof,              ## end of file reached
+    tkIdentifier,       ## abc
+    tkQuotedIdentifier, ## "abc"
+    tkStringConstant,   ## 'abc'
+    tkEscapeConstant,       ## e'abc'
+    tkDollarQuotedConstant, ## $tag$abc$tag$
+    tkBitStringConstant,    ## B'00011'
+    tkHexStringConstant,    ## x'00011'
+    tkInteger,
+    tkNumeric,
+    tkOperator,             ## + - * / < > = ~ ! @ # % ^ & | ` ?
+    tkSemicolon,            ## ';'
+    tkColon,                ## ':'
+    tkComma,                ## ','
+    tkParLe,                ## '('
+    tkParRi,                ## ')'
+    tkBracketLe,            ## '['
+    tkBracketRi,            ## ']'
+    tkDot                   ## '.'
+  
+  TToken {.final.} = object  # a token
+    kind: TTokKind           # the type of the token
+    literal: string          # the parsed (string) literal
+  
+  TSqlLexer* = object of TBaseLexer ## the parser object.
+    filename: string
+
+const
+  tokKindToStr: array[TTokKind, string] = [
+    "invalid", "[EOF]", "identifier", "quoted identifier", "string constant",
+    "escape string constant", "dollar quoted constant", "bit string constant",
+    "hex string constant", "integer constant", "numeric constant", "operator",
+    ";", ":", ",", "(", ")", "[", "]", "."
+  ]
+
+proc open(L: var TSqlLexer, input: PStream, filename: string) = 
+  lexbase.open(L, input)
+  L.filename = filename
+  
+proc close(L: var TSqlLexer) = 
+  lexbase.close(L)
+
+proc getColumn(L: TSqlLexer): int = 
+  ## get the current column the parser has arrived at.
+  result = getColNumber(L, L.bufPos)
+
+proc getLine(L: TSqlLexer): int = 
+  result = L.linenumber
+
+proc handleHexChar(c: var TSqlLexer, xi: var int) = 
+  case c.buf[c.bufpos]
+  of '0'..'9': 
+    xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0'))
+    inc(c.bufpos)
+  of 'a'..'f': 
+    xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10)
+    inc(c.bufpos)
+  of 'A'..'F': 
+    xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10)
+    inc(c.bufpos)
+  else: 
+    nil
+
+proc handleOctChar(c: var TSqlLexer, xi: var int) = 
+  if c.buf[c.bufpos] in {'0'..'7'}:
+    xi = (xi shl 3) or (ord(c.buf[c.bufpos]) - ord('0'))
+    inc(c.bufpos)
+
+proc getEscapedChar(c: var TSqlLexer, tok: var TToken) = 
+  inc(c.bufpos)
+  case c.buf[c.bufpos]
+  of 'n', 'N': 
+    add(tok.literal, '\L')
+    Inc(c.bufpos)
+  of 'r', 'R', 'c', 'C': 
+    add(tok.literal, '\c')
+    Inc(c.bufpos)
+  of 'l', 'L': 
+    add(tok.literal, '\L')
+    Inc(c.bufpos)
+  of 'f', 'F': 
+    add(tok.literal, '\f')
+    inc(c.bufpos)
+  of 'e', 'E': 
+    add(tok.literal, '\e')
+    Inc(c.bufpos)
+  of 'a', 'A': 
+    add(tok.literal, '\a')
+    Inc(c.bufpos)
+  of 'b', 'B': 
+    add(tok.literal, '\b')
+    Inc(c.bufpos)
+  of 'v', 'V': 
+    add(tok.literal, '\v')
+    Inc(c.bufpos)
+  of 't', 'T': 
+    add(tok.literal, '\t')
+    Inc(c.bufpos)
+  of '\'', '\"': 
+    add(tok.literal, c.buf[c.bufpos])
+    Inc(c.bufpos)
+  of '\\': 
+    add(tok.literal, '\\')
+    Inc(c.bufpos)
+  of 'x', 'X': 
+    inc(c.bufpos)
+    var xi = 0
+    handleHexChar(c, xi)
+    handleHexChar(c, xi)
+    add(tok.literal, Chr(xi))
+  of '0'..'7': 
+    var xi = 0
+    handleOctChar(c, xi)
+    handleOctChar(c, xi)
+    handleOctChar(c, xi)
+    if (xi <= 255): add(tok.literal, Chr(xi))
+    else: tok.kind = tkInvalid
+  else: tok.kind = tkInvalid
+  
+proc HandleCRLF(c: var TSqlLexer, pos: int): int = 
+  case c.buf[pos]
+  of '\c': result = lexbase.HandleCR(c, pos)
+  of '\L': result = lexbase.HandleLF(c, pos)
+  else: result = pos
+
+proc skip(c: var TSqlLexer) = 
+  var pos = c.bufpos
+  var buf = c.buf
+  var nested = 0
+  while true: 
+    case buf[pos]
+    of ' ', '\t': 
+      Inc(pos)
+    of '-':
+      if buf[pos+1] == '-':
+        while not (buf[pos] in {'\c', '\L', lexbase.EndOfFile}): inc(pos)
+      else:
+        break
+    of '/':
+      if buf[pos+1] == '*':
+        inc(pos,2)
+        while true:
+          case buf[pos]
+          of '\0': break
+          of '\c', '\L': 
+            pos = HandleCRLF(c, pos)
+            buf = c.buf
+          of '*':
+            if buf[pos+1] == '/':
+              inc(pos, 2)
+              if nested <= 0: break
+              dec(nested)
+            else:
+              inc(pos)
+          of '/':
+            if buf[pos+1] == '*':
+              inc(pos, 2)
+              inc(nested)
+            else:
+              inc(pos)
+          else: inc(pos)
+      else: break
+    of '\c', '\L': 
+      pos = HandleCRLF(c, pos)
+      buf = c.buf
+    else: 
+      break                   # EndOfFile also leaves the loop
+  c.bufpos = pos
+  
+proc getString(c: var TSqlLexer, tok: var TToken, kind: TTokKind) = 
+  var pos = c.bufPos + 1
+  var buf = c.buf
+  tok.kind = kind
+  block parseLoop:
+    while true:
+      while true: 
+        var ch = buf[pos]
+        if ch == '\'':
+          if buf[pos+1] == '\'':
+            inc(pos, 2)
+            add(tok.literal, '\'')
+          else:
+            inc(pos)
+            break 
+        elif ch in {'\c', '\L', lexbase.EndOfFile}: 
+          tok.kind = tkInvalid
+          break parseLoop
+        elif (ch == '\\') and kind == tkEscapeConstant: 
+          c.bufPos = pos
+          getEscapedChar(c, tok)
+          pos = c.bufPos
+        else: 
+          add(tok.literal, ch)
+          Inc(pos)
+      c.bufpos = pos
+      var line = c.linenumber
+      skip(c)
+      if c.linenumber > line:
+        # a new line whitespace has been parsed, so we check if the string
+        # continues after the whitespace:
+        buf = c.buf # may have been reallocated
+        pos = c.bufpos
+        if buf[pos] == '\'': inc(pos)
+        else: break parseLoop
+      else: break parseLoop
+  c.bufpos = pos
+
+proc getDollarString(c: var TSqlLexer, tok: var TToken) = 
+  var pos = c.bufPos + 1
+  var buf = c.buf
+  tok.kind = tkDollarQuotedConstant
+  var tag = "$"
+  while buf[pos] in IdentChars:
+    add(tag, buf[pos])
+    inc(pos)
+  if buf[pos] == '$': inc(pos)
+  else:
+    tok.kind = tkInvalid
+    return
+  while true:
+    case buf[pos]
+    of '\c', '\L': 
+      pos = HandleCRLF(c, pos)
+      buf = c.buf
+      add(tok.literal, "\L")
+    of '\0':
+      tok.kind = tkInvalid
+      break
+    of '$':
+      inc(pos)
+      var tag2 = "$"
+      while buf[pos] in IdentChars:
+        add(tag2, buf[pos])
+        inc(pos)
+      if buf[pos] == '$': inc(pos)
+      if tag2 == tag: break
+      add(tok.literal, tag2)
+      add(tok.literal, '$')
+    else:
+      add(tok.literal, buf[pos])
+      inc(pos)
+  c.bufpos = pos
+
+proc getSymbol(c: var TSqlLexer, tok: var TToken) = 
+  var pos = c.bufpos
+  var buf = c.buf
+  while true: 
+    add(tok.literal, buf[pos])
+    Inc(pos)
+    if not (buf[pos] in {'a'..'z','A'..'Z','0'..'9','_','$', '\128'..'\255'}):
+      break
+  c.bufpos = pos
+  tok.kind = tkIdentifier
+
+proc getQuotedIdentifier(c: var TSqlLexer, tok: var TToken) = 
+  var pos = c.bufPos + 1
+  var buf = c.buf
+  tok.kind = tkQuotedIdentifier
+  while true:
+    var ch = buf[pos]
+    if ch == '\"':
+      if buf[pos+1] == '\"':
+        inc(pos, 2)
+        add(tok.literal, '\"')
+      else:
+        inc(pos)
+        break
+    elif ch in {'\c', '\L', lexbase.EndOfFile}: 
+      tok.kind = tkInvalid
+      break
+    else:
+      add(tok.literal, ch)
+      Inc(pos)
+  c.bufpos = pos
+
+proc getBitHexString(c: var TSqlLexer, tok: var TToken, validChars: TCharSet) =
+  var pos = c.bufPos + 1
+  var buf = c.buf
+  block parseLoop:
+    while true:
+      while true: 
+        var ch = buf[pos]
+        if ch in validChars:
+          add(tok.literal, ch)
+          Inc(pos)          
+        elif ch == '\'':
+          inc(pos)
+          break
+        else: 
+          tok.kind = tkInvalid
+          break parseLoop
+      c.bufpos = pos
+      var line = c.linenumber
+      skip(c)
+      if c.linenumber > line:
+        # a new line whitespace has been parsed, so we check if the string
+        # continues after the whitespace:
+        buf = c.buf # may have been reallocated
+        pos = c.bufpos
+        if buf[pos] == '\'': inc(pos)
+        else: break parseLoop
+      else: break parseLoop
+  c.bufpos = pos
+
+proc getNumeric(c: var TSqlLexer, tok: var TToken) =
+  tok.kind = tkInteger
+  var pos = c.bufPos
+  var buf = c.buf
+  while buf[pos] in Digits:
+    add(tok.literal, buf[pos])
+    inc(pos)
+  if buf[pos] == '.':
+    tok.kind = tkNumeric
+    add(tok.literal, buf[pos])
+    inc(pos)
+    while buf[pos] in Digits:
+      add(tok.literal, buf[pos])
+      inc(pos)
+  if buf[pos] in {'E', 'e'}:
+    tok.kind = tkNumeric
+    add(tok.literal, buf[pos])
+    inc(pos)
+    if buf[pos] == '+':
+      inc(pos)
+    elif buf[pos] == '-':
+      add(tok.literal, buf[pos])
+      inc(pos)
+    if buf[pos] in Digits:
+      while buf[pos] in Digits:
+        add(tok.literal, buf[pos])
+        inc(pos)
+    else:
+      tok.kind = tkInvalid
+  c.bufpos = pos  
+
+proc getOperator(c: var TSqlLexer, tok: var TToken) =
+  const operators = {'+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%',
+                     '^', '&', '|', '`', '?'}
+  tok.kind = tkOperator
+  var pos = c.bufPos
+  var buf = c.buf
+  var trailingPlusMinus = false
+  while true:
+    case buf[pos]
+    of '-':
+      if buf[pos] == '-': break
+      if not trailingPlusMinus and buf[pos+1] notin operators and
+           tok.literal.len > 0: break
+    of '/':
+      if buf[pos] == '*': break
+    of '~', '!', '@', '#', '%', '^', '&', '|', '`', '?':
+      trailingPlusMinus = true
+    of '+':
+      if not trailingPlusMinus and buf[pos+1] notin operators and
+           tok.literal.len > 0: break
+    of '*', '<', '>', '=': nil
+    else: break
+    add(tok.literal, buf[pos])
+    inc(pos)
+  c.bufpos = pos
+
+proc getTok(c: var TSqlLexer, tok: var TToken) = 
+  tok.kind = tkInvalid
+  setlen(tok.literal, 0)
+  skip(c)
+  case c.buf[c.bufpos]
+  of ';': 
+    tok.kind = tkSemiColon
+    inc(c.bufPos)
+    add(tok.literal, ';')
+  of ',':
+    tok.kind = tkComma
+    inc(c.bufpos)
+    add(tok.literal, ',')
+  of ':': 
+    tok.kind = tkColon
+    inc(c.bufpos)
+    add(tok.literal, ':')
+  of 'e', 'E': 
+    if c.buf[c.bufPos + 1] == '\'': 
+      Inc(c.bufPos)
+      getString(c, tok, tkEscapeConstant)
+    else: 
+      getSymbol(c, tok)
+  of 'b', 'B':
+    if c.buf[c.bufPos + 1] == '\'':
+      tok.kind = tkBitStringConstant
+      getBitHexString(c, tok, {'0'..'1'})
+    else:
+      getSymbol(c, tok)
+  of 'x', 'X':
+    if c.buf[c.bufPos + 1] == '\'':
+      tok.kind = tkHexStringConstant
+      getBitHexString(c, tok, {'a'..'f','A'..'F','0'..'9'})
+    else:
+      getSymbol(c, tok)
+  of '$': getDollarString(c, tok)
+  of '[': 
+    tok.kind = tkBracketLe
+    inc(c.bufpos)
+    add(tok.literal, '[')
+  of ']': 
+    tok.kind = tkBracketRi
+    Inc(c.bufpos)
+    add(tok.literal, ']')
+  of '(':
+    tok.kind = tkParLe
+    Inc(c.bufpos)
+    add(tok.literal, '(')
+  of ')':
+    tok.kind = tkParRi
+    Inc(c.bufpos)
+    add(tok.literal, ')')
+  of '.': 
+    if c.buf[c.bufPos + 1] in Digits:
+      getNumeric(c, tok)
+    else:
+      tok.kind = tkDot
+      inc(c.bufpos)
+    add(tok.literal, '.')
+  of '0'..'9': getNumeric(c, tok)
+  of '\'': getString(c, tok, tkStringConstant)
+  of '"': getQuotedIdentifier(c, tok)
+  of lexbase.EndOfFile: 
+    tok.kind = tkEof
+    tok.literal = "[EOF]"
+  of 'a', 'c', 'd', 'f'..'w', 'y', 'z', 'A', 'C', 'D', 'F'..'W', 'Y', 'Z', '_',
+     '\128'..'\255':
+    getSymbol(c, tok)
+  of '+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%',
+     '^', '&', '|', '`', '?':
+    getOperator(c, tok)
+  else:
+    add(tok.literal, c.buf[c.bufpos])
+    inc(c.bufpos)
+  
+proc errorStr(L: TSqlLexer, msg: string): string = 
+  result = "$1($2, $3) Error: $4" % [L.filename, $getLine(L), $getColumn(L), msg]
+
+
+# ----------------------------- parser ----------------------------------------
+
+# Operator/Element	Associativity	Description
+# .	                left    	table/column name separator
+# ::            	left	        PostgreSQL-style typecast
+# [ ]	                left    	array element selection
+# -	                right	        unary minus
+# ^             	left	        exponentiation
+# * / %	                left	        multiplication, division, modulo
+# + -	                left	        addition, subtraction
+# IS	 	IS TRUE, IS FALSE, IS UNKNOWN, IS NULL
+# ISNULL	 	test for null
+# NOTNULL	 	test for not null
+# (any other)	        left    	all other native and user-defined oprs
+# IN	          	set membership
+# BETWEEN	 	range containment
+# OVERLAPS	 	time interval overlap
+# LIKE ILIKE SIMILAR	 	string pattern matching
+# < >	 	less than, greater than
+# =	                right	        equality, assignment
+# NOT	                right	        logical negation
+# AND	                left	        logical conjunction
+# OR              	left	        logical disjunction
+
+type
+  TSqlNodeKind* = enum
+    nkNone,
+    nkIdent,
+    nkStringLit,
+    nkBitStringLit,
+    nkHexStringLit,
+    nkIntegerLit,
+    nkNumericLit,
+    nkPrimaryKey,
+    nkForeignKey,
+    nkNotNull,
+    
+    nkStmtList,
+    nkDot,
+    nkDotDot,
+    nkPrefix,
+    nkInfix,
+    nkCall,
+    nkColumnReference,
+    nkReferences,
+    nkDefault,
+    nkCheck,
+    nkConstraint,
+    nkUnique,
+    nkIdentity,
+    nkColumnDef,        ## name, datatype, constraints
+    nkInsert,
+    nkUpdate,
+    nkDelete,
+    nkSelect,
+    nkSelectDistinct,
+    nkSelectColumns,
+    nkAsgn,
+    nkFrom,
+    nkGroup,
+    nkHaving,
+    nkOrder,
+    nkDesc,
+    nkUnion,
+    nkIntersect,
+    nkExcept,
+    nkColumnList,
+    nkValueList,
+    nkWhere,
+    nkCreateTable,
+    nkCreateTableIfNotExists, 
+    nkCreateType,
+    nkCreateTypeIfNotExists,
+    nkCreateIndex,
+    nkCreateIndexIfNotExists,
+    nkEnumDef
+    
+type
+  EInvalidSql* = object of EBase    
+  PSqlNode* = ref TSqlNode
+  TSqlNode* = object
+    case kind*: TSqlNodeKind
+    of nkIdent, nkStringLit, nkBitStringLit, nkHexStringLit,
+                nkIntegerLit, nkNumericLit:
+      strVal*: string
+    else:
+      sons*: seq[PSqlNode]
+
+  TSqlParser = object of TSqlLexer
+    tok: TToken
+
+proc newNode(k: TSqlNodeKind): PSqlNode =
+  new(result)
+  result.kind = k
+
+proc newNode(k: TSqlNodeKind, s: string): PSqlNode =
+  new(result)
+  result.kind = k
+  result.strVal = s
+  
+proc len*(n: PSqlNode): int =
+  if isNil(n.sons): result = 0
+  else: result = n.sons.len
+  
+proc add*(father, n: PSqlNode) =
+  if isNil(father.sons): father.sons = @[]
+  add(father.sons, n)
+
+proc getTok(p: var TSqlParser) =
+  getTok(p, p.tok)
+
+proc sqlError(p: TSqlParser, msg: string) =
+  var e: ref EInvalidSql
+  e.msg = errorStr(p, msg)
+  raise e
+
+proc isKeyw(p: TSqlParser, keyw: string): bool =
+  result = p.tok.kind == tkIdentifier and
+           cmpIgnoreCase(p.tok.literal, keyw) == 0
+
+proc isOpr(p: TSqlParser, opr: string): bool =
+  result = p.tok.kind == tkOperator and
+           cmpIgnoreCase(p.tok.literal, opr) == 0
+
+proc optKeyw(p: var TSqlParser, keyw: string) =
+  if p.tok.kind == tkIdentifier and cmpIgnoreCase(p.tok.literal, keyw) == 0:
+    getTok(p)
+
+proc expectIdent(p: TSqlParser) =
+  if p.tok.kind != tkIdentifier and p.tok.kind != tkQuotedIdentifier:
+    sqlError(p, "identifier expected")
+
+proc expect(p: TSqlParser, kind: TTokKind) =
+  if p.tok.kind != kind:
+    sqlError(p, tokKindToStr[kind] & " expected")
+
+proc eat(p: var TSqlParser, kind: TTokKind) =
+  if p.tok.kind == kind:
+    getTok(p)
+  else:
+    sqlError(p, tokKindToStr[kind] & " expected")
+
+proc eat(p: var TSqlParser, keyw: string) =
+  if isKeyw(p, keyw):
+    getTok(p)
+  else:
+    sqlError(p, keyw.toUpper() & " expected")
+
+proc parseDataType(p: var TSqlParser): PSqlNode =
+  if isKeyw(p, "enum"):
+    result = newNode(nkEnumDef)
+    getTok(p)
+    if p.tok.kind == tkParLe:
+      getTok(p)
+      result.add(newNode(nkStringLit, p.tok.literal))
+      getTok(p)
+      while p.tok.kind == tkComma:
+        getTok(p)
+        result.add(newNode(nkStringLit, p.tok.literal))
+        getTok(p)
+      eat(p, tkParRi)
+  else:
+    expectIdent(p)
+    result = newNode(nkIdent, p.tok.literal)
+    getTok(p)
+    # ignore (12, 13) part:
+    if p.tok.kind == tkParLe:
+      getTok(p)
+      expect(p, tkInteger)
+      getTok(p)
+      while p.tok.kind == tkComma:
+        getTok(p)
+        expect(p, tkInteger)
+        getTok(p)
+      eat(p, tkParRi)
+
+proc getPrecedence(p: TSqlParser): int = 
+  if isOpr(p, "*") or isOpr(p, "/") or isOpr(p, "%"):
+    result = 6
+  elif isOpr(p, "+") or isOpr(p, "-"):
+    result = 5  
+  elif isOpr(p, "=") or isOpr(p, "<") or isOpr(p, ">") or isOpr(p, ">=") or
+       isOpr(p, "<=") or isOpr(p, "<>") or isOpr(p, "!=") or isKeyw(p, "is") or
+       isKeyw(p, "like"):
+    result = 3
+  elif isKeyw(p, "and"):
+    result = 2
+  elif isKeyw(p, "or"):
+    result = 1
+  elif p.tok.kind == tkOperator:
+    # user-defined operator:
+    result = 0
+  else:
+    result = - 1
+
+proc parseExpr(p: var TSqlParser): PSqlNode
+
+proc identOrLiteral(p: var TSqlParser): PSqlNode = 
+  case p.tok.kind
+  of tkIdentifier, tkQuotedIdentifier: 
+    result = newNode(nkIdent, p.tok.literal)
+    getTok(p)
+  of tkStringConstant, tkEscapeConstant, tkDollarQuotedConstant:
+    result = newNode(nkStringLit, p.tok.literal)
+    getTok(p)
+  of tkBitStringConstant:
+    result = newNode(nkBitStringLit, p.tok.literal)
+    getTok(p)
+  of tkHexStringConstant:
+    result = newNode(nkHexStringLit, p.tok.literal)
+    getTok(p)
+  of tkInteger:
+    result = newNode(nkIntegerLit, p.tok.literal)
+    getTok(p)
+  of tkNumeric:
+    result = newNode(nkNumericLit, p.tok.literal)
+    getTok(p)
+  of tkParLe:
+    getTok(p)
+    result = parseExpr(p)
+    eat(p, tkParRi)
+  else: 
+    sqlError(p, "expression expected")
+    getTok(p) # we must consume a token here to prevend endless loops!
+
+proc primary(p: var TSqlParser): PSqlNode = 
+  if p.tok.kind == tkOperator or isKeyw(p, "not"): 
+    result = newNode(nkPrefix)
+    result.add(newNode(nkIdent, p.tok.literal))
+    getTok(p)
+    result.add(primary(p))
+    return
+  result = identOrLiteral(p)
+  while true: 
+    case p.tok.kind
+    of tkParLe: 
+      var a = result
+      result = newNode(nkCall)
+      result.add(a)
+      getTok(p)
+      while true:
+        result.add(parseExpr(p))
+        if p.tok.kind == tkComma: getTok(p)
+        else: break
+      eat(p, tkParRi)
+    of tkDot: 
+      getTok(p)
+      var a = result
+      if p.tok.kind == tkDot:
+        getTok(p)
+        result = newNode(nkDotDot)
+      else:
+        result = newNode(nkDot)
+      result.add(a)
+      if isOpr(p, "*"):
+        result.add(newNode(nkIdent, "*"))
+      elif p.tok.kind in {tkIdentifier, tkQuotedIdentifier}:
+        result.add(newNode(nkIdent, p.tok.literal))
+      else:
+        sqlError(p, "identifier expected")
+      getTok(p)
+    else: break
+  
+proc lowestExprAux(p: var TSqlParser, v: var PSqlNode, limit: int): int = 
+  var
+    v2, node, opNode: PSqlNode
+  v = primary(p) # expand while operators have priorities higher than 'limit'
+  var opPred = getPrecedence(p)
+  result = opPred
+  while opPred > limit: 
+    node = newNode(nkInfix)
+    opNode = newNode(nkIdent, p.tok.literal)
+    getTok(p)
+    result = lowestExprAux(p, v2, opPred)
+    node.add(opNode)
+    node.add(v)
+    node.add(v2)
+    v = node
+    opPred = getPrecedence(p)
+  
+proc parseExpr(p: var TSqlParser): PSqlNode = 
+  discard lowestExprAux(p, result, - 1)
+
+proc parseTableName(p: var TSqlParser): PSqlNode =
+  expectIdent(p)
+  result = primary(p)
+
+proc parseColumnReference(p: var TSqlParser): PSqlNode =
+  result = parseTableName(p)
+  if p.tok.kind == tkParLe:
+    getTok(p)
+    var a = result
+    result = newNode(nkColumnReference)
+    result.add(a)
+    result.add(parseTableName(p))
+    while p.tok.kind == tkComma:
+      getTok(p)
+      result.add(parseTableName(p))
+    eat(p, tkParRi)
+
+proc parseCheck(p: var TSqlParser): PSqlNode = 
+  getTok(p)
+  result = newNode(nkCheck)
+  result.add(parseExpr(p))
+
+proc parseConstraint(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  result = newNode(nkConstraint)
+  expectIdent(p)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  eat(p, "check")
+  result.add(parseExpr(p))
+
+proc parseColumnConstraints(p: var TSqlParser, result: PSqlNode) =
+  while true:
+    if isKeyw(p, "default"):
+      getTok(p)
+      var n = newNode(nkDefault)
+      n.add(parseExpr(p))
+      result.add(n)
+    elif isKeyw(p, "references"):
+      getTok(p)
+      var n = newNode(nkReferences)
+      n.add(parseColumnReference(p))
+      result.add(n)
+    elif isKeyw(p, "not"):
+      getTok(p)
+      eat(p, "null")
+      result.add(newNode(nkNotNull))
+    elif isKeyw(p, "identity"):
+      getTok(p)
+      result.add(newNode(nkIdentity))
+    elif isKeyw(p, "primary"):
+      getTok(p)
+      eat(p, "key")
+      result.add(newNode(nkPrimaryKey))
+    elif isKeyw(p, "check"):
+      result.add(parseCheck(p))
+    elif isKeyw(p, "constraint"):
+      result.add(parseConstraint(p))
+    elif isKeyw(p, "unique"):
+      result.add(newNode(nkUnique))
+    else:
+      break
+
+proc parseColumnDef(p: var TSqlParser): PSqlNode =
+  expectIdent(p)
+  result = newNode(nkColumnDef)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  result.add(parseDataType(p))
+  parseColumnConstraints(p, result)  
+
+proc parseIfNotExists(p: var TSqlParser, k: TSqlNodeKind): PSqlNode = 
+  getTok(p)
+  if isKeyw(p, "if"):
+    getTok(p)
+    eat(p, "not")
+    eat(p, "exists")
+    result = newNode(succ(k))
+  else:
+    result = newNode(k)
+
+proc parseParIdentList(p: var TSqlParser, father: PSqlNode) =
+  eat(p, tkParLe)
+  while true:
+    expectIdent(p)
+    father.add(newNode(nkIdent, p.tok.literal))
+    getTok(p)
+    if p.tok.kind != tkComma: break
+    getTok(p)
+  eat(p, tkParRi)
+
+proc parseTableConstraint(p: var TSqlParser): PSqlNode =
+  if isKeyw(p, "primary"):
+    getTok(p)
+    eat(p, "key")
+    result = newNode(nkPrimaryKey)
+    parseParIdentList(p, result)
+  elif isKeyw(p, "foreign"):
+    getTok(p)
+    eat(p, "key")
+    result = newNode(nkForeignKey)
+    parseParIdentList(p, result)
+    eat(p, "references")
+    var m = newNode(nkReferences)
+    m.add(parseColumnReference(p))
+    result.add(m)
+  elif isKeyw(p, "unique"):
+    getTok(p)
+    eat(p, "key")
+    result = newNode(nkUnique)
+    parseParIdentList(p, result)
+  elif isKeyw(p, "check"):
+    result = parseCheck(p)
+  elif isKeyw(p, "constraint"):
+    result = parseConstraint(p)
+  else:
+    sqlError(p, "column definition expected")
+
+proc parseTableDef(p: var TSqlParser): PSqlNode =
+  result = parseIfNotExists(p, nkCreateTable)
+  expectIdent(p)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  if p.tok.kind == tkParLe:
+    while true:
+      getTok(p)
+      if p.tok.kind == tkIdentifier or p.tok.kind == tkQuotedIdentifier:
+        result.add(parseColumnDef(p))
+      else:
+        result.add(parseTableConstraint(p))
+      if p.tok.kind != tkComma: break
+    eat(p, tkParRi)
+  
+proc parseTypeDef(p: var TSqlParser): PSqlNode =
+  result = parseIfNotExists(p, nkCreateType)
+  expectIdent(p)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  eat(p, "as")
+  result.add(parseDataType(p))
+
+proc parseWhere(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  result = newNode(nkWhere)
+  result.add(parseExpr(p))
+
+proc parseIndexDef(p: var TSqlParser): PSqlNode =
+  result = parseIfNotExists(p, nkCreateIndex)
+  if isKeyw(p, "primary"):
+    getTok(p)
+    eat(p, "key")
+    result.add(newNode(nkPrimaryKey))
+  else:
+    expectIdent(p)
+    result.add(newNode(nkIdent, p.tok.literal))
+    getTok(p)
+  eat(p, "on")
+  expectIdent(p)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  eat(p, tkParLe)
+  expectIdent(p)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  while p.tok.kind == tkComma:
+    getTok(p)
+    expectIdent(p)
+    result.add(newNode(nkIdent, p.tok.literal))
+    getTok(p)
+  eat(p, tkParRi)
+
+proc parseInsert(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  eat(p, "into")
+  expectIdent(p)
+  result = newNode(nkInsert)
+  result.add(newNode(nkIdent, p.tok.literal))
+  getTok(p)
+  if p.tok.kind == tkParLe:
+    var n = newNode(nkColumnList)
+    parseParIdentList(p, n)
+  else:
+    result.add(nil)
+  if isKeyw(p, "default"):
+    getTok(p)
+    eat(p, "values")
+    result.add(newNode(nkDefault))
+  else:
+    eat(p, "values")
+    eat(p, tkParLe)
+    var n = newNode(nkValueList)
+    while true:
+      n.add(parseExpr(p))
+      if p.tok.kind != tkComma: break
+      getTok(p)
+    result.add(n)
+    eat(p, tkParRi)
+
+proc parseUpdate(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  result = newNode(nkUpdate)
+  result.add(primary(p))
+  eat(p, "set")
+  while true:
+    var a = newNode(nkAsgn)
+    expectIdent(p)
+    a.add(newNode(nkIdent, p.tok.literal))
+    getTok(p)
+    if isOpr(p, "="): getTok(p)
+    else: sqlError(p, "= expected")
+    a.add(parseExpr(p))
+    result.add(a)
+    if p.tok.kind != tkComma: break
+    getTok(p)
+  if isKeyw(p, "where"):
+    result.add(parseWhere(p))
+  else:
+    result.add(nil)
+    
+proc parseDelete(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  result = newNode(nkDelete)
+  eat(p, "from")
+  result.add(primary(p))
+  if isKeyw(p, "where"):
+    result.add(parseWhere(p))
+  else:
+    result.add(nil)
+
+proc parseSelect(p: var TSqlParser): PSqlNode =
+  getTok(p)
+  if isKeyw(p, "distinct"):
+    getTok(p)
+    result = newNode(nkSelectDistinct)
+  elif isKeyw(p, "all"):
+    getTok(p)
+  result = newNode(nkSelect)
+  var a = newNode(nkSelectColumns)
+  while true:
+    if isOpr(p, "*"):
+      a.add(newNode(nkIdent, "*"))
+      getTok(p)
+    else:
+      a.add(parseExpr(p))
+    if p.tok.kind != tkComma: break
+    getTok(p)
+  result.add(a)
+  if isKeyw(p, "from"):
+    var f = newNode(nkFrom)
+    while true:
+      getTok(p)
+      f.add(parseExpr(p))
+      if p.tok.kind != tkComma: break
+    result.add(f)
+  if isKeyw(p, "where"):
+    result.add(parseWhere(p))
+  if isKeyw(p, "group"):
+    getTok(p)
+    eat(p, "by")
+    var g = newNode(nkGroup)
+    while true:
+      g.add(parseExpr(p))
+      if p.tok.kind != tkComma: break
+      getTok(p)
+    result.add(g)
+  if isKeyw(p, "having"):
+    var h = newNode(nkHaving)
+    while true:
+      getTok(p)
+      h.add(parseExpr(p))
+      if p.tok.kind != tkComma: break    
+    result.add(h)
+  if isKeyw(p, "union"):
+    result.add(newNode(nkUnion))
+    getTok(p)
+  elif isKeyw(p, "intersect"):
+    result.add(newNode(nkIntersect))
+    getTok(p)  
+  elif isKeyw(p, "except"):
+    result.add(newNode(nkExcept))
+    getTok(p)
+  if isKeyw(p, "order"):
+    getTok(p)
+    eat(p, "by")
+    var n = newNode(nkOrder)
+    while true:
+      var e = parseExpr(p)
+      if isKeyw(p, "asc"): getTok(p) # is default
+      elif isKeyw(p, "desc"):
+        getTok(p)
+        var x = newNode(nkDesc)
+        x.add(e)
+        e = x
+      n.add(e)
+      if p.tok.kind != tkComma: break
+      getTok(p)
+    result.add(n)
+
+proc parseStmt(p: var TSqlParser): PSqlNode =
+  if isKeyw(p, "create"):
+    getTok(p)
+    optKeyw(p, "cached")
+    optKeyw(p, "memory")
+    optKeyw(p, "temp")
+    optKeyw(p, "global")
+    optKeyw(p, "local")
+    optKeyw(p, "temporary")
+    optKeyw(p, "unique")
+    optKeyw(p, "hash")
+    if isKeyw(p, "table"):
+      result = parseTableDef(p)
+    elif isKeyw(p, "type"):
+      result = parseTypeDef(p)
+    elif isKeyw(p, "index"):
+      result = parseIndexDef(p)
+    else:
+      sqlError(p, "TABLE expected")
+  elif isKeyw(p, "insert"):
+    result = parseInsert(p)
+  elif isKeyw(p, "update"):
+    result = parseUpdate(p)
+  elif isKeyw(p, "delete"):
+    result = parseDelete(p)
+  elif isKeyw(p, "select"):
+    result = parseSelect(p)
+  else:
+    sqlError(p, "CREATE expected")
+
+proc parse*(p: var TSqlParser): PSqlNode =
+  result = newNode(nkStmtList)
+  while p.tok.kind != tkEof:
+    var s = parseStmt(p)
+    eat(p, tkSemiColon)
+    result.add(s)
+  if result.len == 1:
+    result = result.sons[0]
+
+proc open*(p: var TSqlParser, input: PStream, filename: string) =
+  open(TSqlLexer(p), input, filename)
+  p.tok.kind = tkInvalid
+  p.tok.literal = ""
+  getTok(p)
+  
+proc close*(p: var TSqlParser) = 
+  close(TSqlLexer(p))
+
+proc parseSQL*(input: PStream, filename: string): PSqlNode =
+  var p: TSqlParser
+  open(p, input, filename)
+  result = parse(p)
+  close(p)
+
+proc ra(n: PSqlNode, s: var string, indent: int)
+
+proc rs(n: PSqlNode, s: var string, indent: int,
+        prefix = "(", suffix = ")",
+        sep = ", ") = 
+  if n.len > 0:
+    s.add(prefix)
+    for i in 0 .. n.len-1:
+      if i > 0: s.add(sep)
+      ra(n.sons[i], s, indent)
+    s.add(suffix)
+
+proc ra(n: PSqlNode, s: var string, indent: int) =
+  if n == nil: return
+  case n.kind
+  of nkNone: nil
+  of nkIdent:
+    if allCharsInSet(n.strVal, {'\33'..'\127'}):
+      s.add(n.strVal)
+    else:
+      s.add("\"" & replaceStr(n.strVal, "\"", "\"\"") & "\"")
+  of nkStringLit:
+    s.add(escape(n.strVal, "e'", "'"))
+  of nkBitStringLit:
+    s.add("b'" & n.strVal & "'")
+  of nkHexStringLit:
+    s.add("x'" & n.strVal & "'")
+  of nkIntegerLit, nkNumericLit:
+    s.add(n.strVal)
+  of nkPrimaryKey:
+    s.add(" primary key")
+    rs(n, s, indent)
+  of nkForeignKey:
+    s.add(" foreign key")
+    rs(n, s, indent)
+  of nkNotNull:
+    s.add(" not null")
+  of nkDot:
+    ra(n.sons[0], s, indent)
+    s.add(".")
+    ra(n.sons[1], s, indent)
+  of nkDotDot:
+    ra(n.sons[0], s, indent)
+    s.add(". .")
+    ra(n.sons[1], s, indent)
+  of nkPrefix:
+    s.add('(')
+    ra(n.sons[0], s, indent)
+    s.add(' ')
+    ra(n.sons[1], s, indent)
+    s.add(')')
+  of nkInfix:
+    s.add('(')    
+    ra(n.sons[1], s, indent)
+    s.add(' ')
+    ra(n.sons[0], s, indent)
+    s.add(' ')
+    ra(n.sons[2], s, indent)
+    s.add(')')
+  of nkCall, nkColumnReference:
+    ra(n.sons[0], s, indent)
+    s.add('(')
+    for i in 1..n.len-1:
+      if i > 1: s.add(", ")
+      ra(n.sons[i], s, indent)
+    s.add(')')
+  of nkReferences:
+    s.add(" references ")
+    ra(n.sons[0], s, indent)
+  of nkDefault:
+    s.add(" default ")
+    ra(n.sons[0], s, indent)
+  of nkCheck:
+    s.add(" check ")
+    ra(n.sons[0], s, indent)
+  of nkConstraint:
+    s.add(" constraint ")
+    ra(n.sons[0], s, indent)
+    s.add(" check ")
+    ra(n.sons[1], s, indent)
+  of nkUnique:
+    s.add(" unique")
+    rs(n, s, indent)
+  of nkIdentity:
+    s.add(" identity")
+  of nkColumnDef:
+    s.add("\n  ")
+    rs(n, s, indent, "", "", " ")
+  of nkStmtList:
+    for i in 0..n.len-1:
+      ra(n.sons[i], s, indent)
+      s.add("\n")
+  of nkInsert:
+    assert n.len == 3
+    s.add("insert into ")
+    ra(n.sons[0], s, indent)
+    ra(n.sons[1], s, indent)
+    if n.sons[2].kind == nkDefault: 
+      s.add("default values")
+    else:
+      s.add("\nvalues ")
+      ra(n.sons[2], s, indent)
+    s.add(';')
+  of nkUpdate: 
+    s.add("update ")
+    ra(n.sons[0], s, indent)
+    s.add(" set ")
+    var L = n.len
+    for i in 1 .. L-2:
+      if i > 1: s.add(", ")
+      var it = n.sons[i]
+      assert it.kind == nkAsgn
+      ra(it, s, indent)
+    ra(n.sons[L-1], s, indent)
+    s.add(';')
+  of nkDelete: 
+    s.add("delete from ")
+    ra(n.sons[0], s, indent)
+    ra(n.sons[1], s, indent)
+    s.add(';')
+  of nkSelect, nkSelectDistinct:
+    s.add("select ")
+    if n.kind == nkSelectDistinct:
+      s.add("distinct ")
+    rs(n.sons[0], s, indent, "", "", ", ")
+    for i in 1 .. n.len-1: ra(n.sons[i], s, indent)
+    s.add(';')
+  of nkSelectColumns: 
+    assert(false)
+  of nkAsgn:
+    ra(n.sons[0], s, indent)
+    s.add(" = ")
+    ra(n.sons[1], s, indent)  
+  of nkFrom:
+    s.add("\nfrom ")
+    rs(n, s, indent, "", "", ", ")
+  of nkGroup:
+    s.add("\ngroup by")
+    rs(n, s, indent, "", "", ", ")
+  of nkHaving:
+    s.add("\nhaving")
+    rs(n, s, indent, "", "", ", ")
+  of nkOrder:
+    s.add("\norder by ")
+    rs(n, s, indent, "", "", ", ")
+  of nkDesc:
+    ra(n.sons[0], s, indent)
+    s.add(" desc")
+  of nkUnion:
+    s.add(" union")
+  of nkIntersect:
+    s.add(" intersect")
+  of nkExcept:
+    s.add(" except")
+  of nkColumnList:
+    rs(n, s, indent)
+  of nkValueList:
+    s.add("values ")
+    rs(n, s, indent)
+  of nkWhere:
+    s.add("\nwhere ")
+    ra(n.sons[0], s, indent)
+  of nkCreateTable, nkCreateTableIfNotExists:
+    s.add("create table ")
+    if n.kind == nkCreateTableIfNotExists:
+      s.add("if not exists ")
+    ra(n.sons[0], s, indent)
+    s.add('(')
+    for i in 1..n.len-1:
+      if i > 1: s.add(", ")
+      ra(n.sons[i], s, indent)
+    s.add(");")
+  of nkCreateType, nkCreateTypeIfNotExists:
+    s.add("create type ")
+    if n.kind == nkCreateTypeIfNotExists:
+      s.add("if not exists ")
+    ra(n.sons[0], s, indent)
+    s.add(" as ")
+    ra(n.sons[1], s, indent)
+    s.add(';')
+  of nkCreateIndex, nkCreateIndexIfNotExists:
+    s.add("create index ")
+    if n.kind == nkCreateIndexIfNotExists:
+      s.add("if not exists ")
+    ra(n.sons[0], s, indent)
+    s.add(" on ")
+    ra(n.sons[1], s, indent)
+    s.add('(')
+    for i in 2..n.len-1:
+      if i > 2: s.add(", ")
+      ra(n.sons[i], s, indent)
+    s.add(");")
+  of nkEnumDef:
+    s.add("enum ")
+    rs(n, s, indent)
+
+# What I want: 
+#
+#select(columns = [T1.all, T2.name], 
+#       fromm = [T1, T2],
+#       where = T1.name ==. T2.name,
+#       orderby = [name]):
+#  
+#for row in dbQuery(db, """select x, y, z 
+#                          from a, b 
+#                          where a.name = b.name"""):
+#  
+
+#select x, y, z:
+#  fromm: Table1, Table2
+#  where: x.name == y.name
+#db.select(fromm = [t1, t2], where = t1.name == t2.name):
+#for x, y, z in db.select(fromm = a, b where = a.name == b.name): 
+#  writeln x, y, z
+
+proc renderSQL*(n: PSqlNode): string =
+  ## Converts an SQL abstract syntax tree to its string representation.
+  result = ""
+  ra(n, result, 0)
+
+when isMainModule:
+  echo(renderSQL(parseSQL(newStringStream("""
+      CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
+      CREATE TABLE holidays (
+         num_weeks int,
+         happiness happiness
+      );
+      CREATE INDEX table1_attr1 ON table1(attr1);
+      
+      SELECT * FROM myTab WHERE col1 = 'happy';
+  """), "stdin")))
+
+# CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
+# CREATE TABLE holidays (
+#    num_weeks int,
+#    happiness happiness
+# );
+# CREATE INDEX table1_attr1 ON table1(attr1)
diff --git a/lib/parsexml.nim b/lib/pure/parsexml.nim
index 78be404d1..242a4f01c 100644
--- a/lib/parsexml.nim
+++ b/lib/pure/parsexml.nim
@@ -215,9 +215,11 @@ proc parseCDATA(my: var TXMLParser) =
       break
     of '\c': 
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     else:
       add(my.a, buf[pos])
@@ -241,9 +243,11 @@ proc parseComment(my: var TXMLParser) =
       break
     of '\c': 
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf
       if my.options.contains(reportComments): add(my.a, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       if my.options.contains(reportComments): add(my.a, '\L')
     else:
       if my.options.contains(reportComments): add(my.a, buf[pos])
@@ -262,9 +266,11 @@ proc parseWhitespace(my: var TXmlParser, skip=False) =
     of '\c':  
       # the specification says that CR-LF, CR are to be transformed to LF
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf
       if not skip: add(my.a, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       if not skip: add(my.a, '\L')
     else:
       break
@@ -358,9 +364,11 @@ proc parsePI(my: var TXmlParser) =
     of '\c':  
       # the specification says that CR-LF, CR are to be transformed to LF
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf      
       add(my.b, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       add(my.b, '\L')
     else:
       add(my.b, buf[pos])
@@ -391,9 +399,11 @@ proc parseSpecial(my: var TXmlParser) =
       add(my.a, '>')
     of '\c':  
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     else:
       add(my.a, buf[pos])
@@ -474,9 +484,11 @@ proc parseAttribute(my: var TXmlParser) =
         inc(pos)
       of '\c':  
         pos = lexbase.HandleCR(my, pos)
+        buf = my.buf
         pendingSpace = true
       of '\L': 
         pos = lexbase.HandleLF(my, pos)
+        buf = my.buf
         pendingSpace = true
       else:
         if buf[pos] == quote:
@@ -502,9 +514,11 @@ proc parseCharData(my: var TXmlParser) =
     of '\c':  
       # the specification says that CR-LF, CR are to be transformed to LF
       pos = lexbase.HandleCR(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     of '\L': 
       pos = lexbase.HandleLF(my, pos)
+      buf = my.buf
       add(my.a, '\L')
     else:
       add(my.a, buf[pos])
diff --git a/lib/base/regexprs.nim b/lib/pure/regexprs.nim
index e2aac3d17..e2aac3d17 100644
--- a/lib/base/regexprs.nim
+++ b/lib/pure/regexprs.nim
diff --git a/lib/streams.nim b/lib/pure/streams.nim
index 238cba4ec..238cba4ec 100644
--- a/lib/streams.nim
+++ b/lib/pure/streams.nim
diff --git a/lib/strtabs.nim b/lib/pure/strtabs.nim
index 10cd0b933..10cd0b933 100644
--- a/lib/strtabs.nim
+++ b/lib/pure/strtabs.nim
diff --git a/lib/strutils.nim b/lib/pure/strutils.nim
index 075e6b252..a4895110b 100644
--- a/lib/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -393,6 +393,17 @@ proc endsWith(s, suffix: string): bool =
     if s[i+j] != suffix[i]: return false
     inc(i)
 
+when false:
+  proc abbrev(s: string, possibilities: openarray[string]): int = 
+    ## returns the index of the first item in `possibilities` if not
+    ## ambigious; -1 if no item has been found; -2 if multiple items
+    ## match.
+    result = -1 # none found
+    for i in 0..possibilities.len-1: 
+      if possibilities[i].startsWith(s): 
+        if result >= 0: return -2 # ambigious
+        result = i
+
 proc repeatChar(count: int, c: Char = ' '): string =
   result = newString(count)
   for i in 0..count-1:
diff --git a/lib/base/terminal.nim b/lib/pure/terminal.nim
index 42bd80cb4..42bd80cb4 100644
--- a/lib/base/terminal.nim
+++ b/lib/pure/terminal.nim
diff --git a/lib/times.nim b/lib/pure/times.nim
index 459b6c2ad..793b55ead 100644
--- a/lib/times.nim
+++ b/lib/pure/times.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
+#        (c) Copyright 2009 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -22,10 +22,19 @@ type
     mJan, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec
   TWeekDay* = enum ## represents a weekday
     dMon, dTue, dWed, dThu, dFri, dSat, dSun
-
-  TTime* {.importc: "time_t", header: "<time.h>", final.} = object ## abstract type that 
-                                                                   ## represents a time
-    when defined(ECMAScript):
+    
+when defined(posix): 
+  type
+    TTime* = abstract int ## abstract type that represents a time
+elif defined(windows):
+  when defined(vcc):
+    # newest version of Visual C++ defines time_t to be of 64 bits
+    type TTime* = abstract int64
+  else:
+    type TTime* = abstract int32
+elif defined(ECMAScript):
+  type
+    TTime* {.final.} = object
       getDay: proc (): int
       getFullYear: proc (): int
       getHours: proc (): int
@@ -64,7 +73,7 @@ type
       toLocaleString: proc (): cstring
       UTC: proc (): int
 
-
+type
   TTimeInfo* = object of TObject ## represents a time in different parts
     second*: range[0..61]     ## The number of seconds after the minute,
                               ## normally in the range 0 to 59, but can
@@ -121,8 +130,7 @@ proc getStartMilsecs*(): int
   ## get the miliseconds from the start of the program
 
 
-when not defined(ECMAScript):
-  
+when not defined(ECMAScript):  
   # C wrapper:
   type
     structTM {.importc: "struct tm", final.} = object
@@ -225,6 +233,18 @@ when not defined(ECMAScript):
     var a = time
     return toStringTillNL(ctime(addr(a)))
 
+  const
+    epochDiff = 116444736000000000'i64
+    rateDiff = 10000000'i64 # 100 nsecs
+
+  proc unixTimeToWinTime*(t: TTime): int64 = 
+    ## converts a UNIX `TTime` (``time_t``) to a Windows file time
+    result = int64(t) * rateDiff + epochDiff
+    
+  proc winTimeToUnixTime*(t: int64): TTime = 
+    ## converts a Windows time to a UNIX `TTime` (``time_t``)
+    result = TTime((t - epochDiff) div rateDiff)
+
 else:
   proc getTime(): TTime {.importc: "new Date", nodecl.}
 
diff --git a/lib/unicode.nim b/lib/pure/unicode.nim
index 70a18f70d..735713cf5 100644
--- a/lib/unicode.nim
+++ b/lib/pure/unicode.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
+#        (c) Copyright 2009 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
diff --git a/lib/xmlgen.nim b/lib/pure/xmlgen.nim
index 79a782252..79a782252 100644
--- a/lib/xmlgen.nim
+++ b/lib/pure/xmlgen.nim
diff --git a/lib/system.nim b/lib/system.nim
index 3be233b50..5f7eefa45 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -38,7 +38,7 @@ type
   string* {.magic: String.} ## built-in string type
   cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type
   pointer* {.magic: Pointer.} ## built-in pointer type
-  TAnyEnum {.magic: AnyEnum.}
+  Ordinal* {.magic: Ordinal.}[T]
 
 type
   `nil` {.magic: "Nil".}
@@ -115,7 +115,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
       data: array[0..100_000_000, char]
     NimString = ptr NimStringDesc
 
-  include hti
+  include "system/hti"
 
 type
   Byte* = Int8 ## this is an alias for ``int8``, that is a signed
@@ -157,6 +157,8 @@ type
                               ## system raises.
   EIO* = object of ESystem    ## raised if an IO error occured.
   EOS* = object of ESystem    ## raised if an operating system service failed.
+  EInvalidLibrary* = object of EOS ## raised if a dynamic library
+                                   ## could not be loaded.
   ERessourceExhausted* = object of ESystem ## raised if a ressource request
                                            ## could not be fullfilled.
   EArithmetic* = object of ESynch       ## raised if any kind of arithmetic
@@ -218,26 +220,26 @@ proc sizeof*[T](x: T): natural {.magic: "SizeOf", noSideEffect.}
   ## that one never needs to know ``x``'s size. As a special semantic rule,
   ## ``x`` may also be a type identifier (``sizeof(int)`` is valid).
 
-proc succ*[T](x: T, y = 1): T {.magic: "Succ", noSideEffect.}
+proc succ*[T](x: ordinal[T], y = 1): T {.magic: "Succ", noSideEffect.}
   ## returns the ``y``-th successor of the value ``x``. ``T`` has to be
   ## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised
   ## or a compile time error occurs.
 
-proc pred*[T](x: T, y = 1): T {.magic: "Pred", noSideEffect.}
+proc pred*[T](x: ordinal[T], y = 1): T {.magic: "Pred", noSideEffect.}
   ## returns the ``y``-th predecessor of the value ``x``. ``T`` has to be
   ## an ordinal type. If such a value does not exist, ``EOutOfRange`` is raised
   ## or a compile time error occurs.
 
-proc inc*[T](x: var T, y = 1) {.magic: "Inc".}
+proc inc*[T](x: var ordinal[T], y = 1) {.magic: "Inc".}
   ## increments the ordinal ``x`` by ``y``. If such a value does not
   ## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a
   ## short notation for: ``x = succ(x, y)``.
 
-proc dec*[T](x: var T, y = 1) {.magic: "Dec".}
+proc dec*[T](x: var ordinal[T], y = 1) {.magic: "Dec".}
   ## decrements the ordinal ``x`` by ``y``. If such a value does not
   ## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a
   ## short notation for: ``x = pred(x, y)``.
-
+  
 proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq".}
   ## creates a new sequence of type ``seq[T]`` with length ``len``.
   ## This is equivalent to ``s = []; setlen(s, len)``, but more
@@ -546,7 +548,7 @@ proc `-+-` *[T](x, y: set[T]): set[T] {.magic: "SymDiffSet", noSideEffect.}
   ## ``(A - B) + (B - A)``, but more efficient.
 
 # comparison operators:
-proc `==` *(x, y: TAnyEnum): bool {.magic: "EqEnum", noSideEffect.}
+proc `==` *[T](x, y: ordinal[T]): bool {.magic: "EqEnum", noSideEffect.}
 proc `==` *(x, y: pointer): bool {.magic: "EqRef", noSideEffect.}
 proc `==` *(x, y: string): bool {.magic: "EqStr", noSideEffect.}
 proc `==` *(x, y: cstring): bool {.magic: "EqCString", noSideEffect.}
@@ -556,7 +558,7 @@ proc `==` *[T](x, y: set[T]): bool {.magic: "EqSet", noSideEffect.}
 proc `==` *[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect.}
 proc `==` *[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect.}
 
-proc `<=` *(x, y: TAnyEnum): bool {.magic: "LeEnum", noSideEffect.}
+proc `<=` *[T](x, y: ordinal[T]): bool {.magic: "LeEnum", noSideEffect.}
 proc `<=` *(x, y: string): bool {.magic: "LeStr", noSideEffect.}
 proc `<=` *(x, y: char): bool {.magic: "LeCh", noSideEffect.}
 proc `<=` *[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect.}
@@ -564,7 +566,7 @@ proc `<=` *(x, y: bool): bool {.magic: "LeB", noSideEffect.}
 proc `<=` *[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect.}
 proc `<=` *(x, y: pointer): bool {.magic: "LePtr", noSideEffect.}
 
-proc `<` *(x, y: TAnyEnum): bool {.magic: "LtEnum", noSideEffect.}
+proc `<` *[T](x, y: ordinal[T]): bool {.magic: "LtEnum", noSideEffect.}
 proc `<` *(x, y: string): bool {.magic: "LtStr", noSideEffect.}
 proc `<` *(x, y: char): bool {.magic: "LtCh", noSideEffect.}
 proc `<` *[T](x, y: set[T]): bool {.magic: "LtSet", noSideEffect.}
@@ -925,7 +927,7 @@ proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
   ## as it is. This operator is useful for generic code, so
   ## that ``$expr`` also works if ``expr`` is already a string.
 
-proc `$` *(x: TAnyEnum): string {.magic: "EnumToStr", noSideEffect.}
+proc `$` *[T](x: ordinal[T]): string {.magic: "EnumToStr", noSideEffect.}
   ## The stingify operator for an enumeration argument. This works for
   ## any enumeration type thanks to compiler magic. If a
   ## a ``$`` operator for a concrete enumeration is provided, this is
@@ -1182,15 +1184,10 @@ proc GC_unref*(x: string) {.magic: "GCunref".}
 # however, stack-traces are available for most parts
 # of the code
 
-proc echo*[Ty](x: Ty) {.inline.}
-  ## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
-  ## available for the ECMAScript target too!
-
-proc echo*[Ty](x: openarray[Ty]) {.inline.}
+proc echo*[Ty](x: openarray[Ty]) {.magic: "Echo".}
   ## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
   ## available for the ECMAScript target too!
 
-
 template newException(exceptn, message: expr): expr =
   block: # open a new scope
     var
@@ -1235,7 +1232,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
 
   {.push stack_trace: off.}
 
-  include ansi_c
+  include "system/ansi_c"
 
   proc cmp(x, y: string): int =
     return int(c_strcmp(x, y))
@@ -1390,7 +1387,7 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     ## retrieves the current position of the file pointer that is used to
     ## read from the file `f`. The file's first byte has the index zero.
 
-  include sysio
+  include "system/sysio"
 
   iterator lines*(filename: string): string =
     ## Iterate over any line in the file named `filename`.
@@ -1416,12 +1413,12 @@ when not defined(EcmaScript) and not defined(NimrodVM):
 
   # ----------------------------------------------------------------------------
 
-  include excpt
+  include "system/excpt"
   # we cannot compile this with stack tracing on
   # as it would recurse endlessly!
-  include arithm
+  include "system/arithm"
   {.pop.} # stack trace
-  include dyncalls
+  include "system/dyncalls"
 
   const
     GenericSeqSize = (2 * sizeof(int))
@@ -1448,10 +1445,10 @@ when not defined(EcmaScript) and not defined(NimrodVM):
     else:
       result = n.sons[n.len]
 
-  include mm
-  include sysstr
-  include assign
-  include repr
+  include "system/mm"
+  include "system/sysstr"
+  include "system/assign"
+  include "system/repr"
 
   # we have to implement it here after gentostr for the cstrToNimStrDummy proc
   proc getCurrentExceptionMsg(): string =
@@ -1460,14 +1457,14 @@ when not defined(EcmaScript) and not defined(NimrodVM):
 
   {.push stack_trace: off.}
   when defined(endb):
-    include debugger
+    include "system/debugger"
 
   when defined(profiler):
-    include profiler
+    include "system/profiler"
   {.pop.} # stacktrace
 
 elif defined(ecmaScript):
-  include ecmasys
+  include "system/ecmasys"
 elif defined(NimrodVM):
   # Stubs for the GC interface:
   proc GC_disable() = nil
@@ -1481,8 +1478,6 @@ elif defined(NimrodVM):
   proc getOccupiedMem(): int = return -1
   proc getFreeMem(): int = return -1
   proc getTotalMem(): int = return -1
-  proc echo[Ty](x: Ty) = nil
-  proc echo[Ty](x: openarray[Ty]) = nil
   
   proc cmp(x, y: string): int =
     if x == y: return 0
diff --git a/lib/alloc.nim b/lib/system/alloc.nim
index 95feff854..95feff854 100644
--- a/lib/alloc.nim
+++ b/lib/system/alloc.nim
diff --git a/lib/ansi_c.nim b/lib/system/ansi_c.nim
index f307fb9ab..bdde11d50 100644
--- a/lib/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -11,10 +11,12 @@
 # and definitions of Ansi C types in Nimrod syntax
 # All symbols are prefixed with 'c_' to avoid ambiguities
 
+{.push hints:off}
+
 proc c_strcmp(a, b: CString): cint {.nodecl, importc: "strcmp".}
 proc c_memcmp(a, b: CString, size: cint): cint {.nodecl, importc: "memcmp".}
 proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
-proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
+proc c_strlen(a: CString): int {.nodecl, importc: "strlen".}
 proc c_memset(p: pointer, value: cint, size: int) {.nodecl, importc: "memset".}
 
 type
@@ -87,3 +89,16 @@ proc c_feof(stream: C_TextFileStar): bool {.importc: "feof", nodecl.}
 proc c_malloc(size: int): pointer {.importc: "malloc", nodecl.}
 proc c_free(p: pointer) {.importc: "free", nodecl.}
 proc c_realloc(p: pointer, newsize: int): pointer {.importc: "realloc", nodecl.}
+
+var errno {.importc, header: "<errno.h>".}: cint ## error variable
+proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".}
+
+proc c_remove(filename: CString): cint {.importc: "remove", noDecl.}
+proc c_rename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
+
+proc c_system(cmd: CString): cint {.importc: "system", header: "<stdlib.h>".}
+proc c_getenv(env: CString): CString {.importc: "getenv", noDecl.}
+proc c_putenv(env: CString): cint {.importc: "putenv", noDecl.}
+
+{.pop}
+
diff --git a/lib/arithm.nim b/lib/system/arithm.nim
index a0e8e3338..a0e8e3338 100644
--- a/lib/arithm.nim
+++ b/lib/system/arithm.nim
diff --git a/lib/assign.nim b/lib/system/assign.nim
index 3d4bf4d61..3d4bf4d61 100644
--- a/lib/assign.nim
+++ b/lib/system/assign.nim
diff --git a/lib/cellsets.nim b/lib/system/cellsets.nim
index 0ce83864c..0ce83864c 100644
--- a/lib/cellsets.nim
+++ b/lib/system/cellsets.nim
diff --git a/lib/cntbits.nim b/lib/system/cntbits.nim
index a975f38ae..a975f38ae 100644
--- a/lib/cntbits.nim
+++ b/lib/system/cntbits.nim
diff --git a/lib/debugger.nim b/lib/system/debugger.nim
index 73a1e4db2..73a1e4db2 100644
--- a/lib/debugger.nim
+++ b/lib/system/debugger.nim
diff --git a/lib/dyncalls.nim b/lib/system/dyncalls.nim
index c46b8a931..c0371d069 100644
--- a/lib/dyncalls.nim
+++ b/lib/system/dyncalls.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2006 Andreas Rumpf
+#        (c) Copyright 2009 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -13,9 +13,6 @@
 # account and been ported to all major platforms.
 
 type
-  EInvalidLibrary = object of EOS
-
-type
   TLibHandle = pointer       # private type
   TProcAddr = pointer        # libary loading and loading of procs:
 
@@ -26,6 +23,9 @@ proc nimLoadLibrary(path: string): TLibHandle {.compilerproc.}
 proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
 proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
 
+proc nimLoadLibraryError(path: string) {.compilerproc, noinline.} =
+  raise newException(EInvalidLibrary, "could not load: " & path)
+
 # this code was inspired from Lua's source code:
 # Lua - An Extensible Extension Language
 # Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
@@ -57,11 +57,6 @@ when defined(posix):
 
   proc nimLoadLibrary(path: string): TLibHandle =
     result = dlopen(path, RTLD_NOW)
-    if result == nil:
-      writeToStdErr("could not load: ")
-      writeToStdErr(path)
-      writeToStdErr("\n")
-      #raise newException(EInvalidLibrary, "could not load: " & path)
 
   proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
     result = dlsym(lib, name)
@@ -86,11 +81,6 @@ elif defined(windows) or defined(dos):
 
   proc nimLoadLibrary(path: string): TLibHandle =
     result = cast[TLibHandle](winLoadLibrary(path))
-    if result == nil:
-      writeToStdErr("could not load: ")
-      writeToStdErr(path)
-      writeToStdErr("\n")
-      #raise newException(EInvalidLibrary, "could not load: " & path)
 
   proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
     result = GetProcAddress(cast[THINSTANCE](lib), name)
@@ -123,11 +113,6 @@ elif defined(mac):
                                         NSLINKMODULE_OPTION_RETURN_ON_ERROR)
         NSDestroyObjectFileImage(img)
         result = TLibHandle(modul)
-        if result == nil:
-          writeToStdErr("could not load: ")
-          writeToStdErr(path)
-          writeToStdErr("\n")          
-          #raise newException(EInvalidLibrary, "could not load: " & path)
 
   proc nimGetProcAddr(lib: TLibHandle, cname: string): TProcAddr =
     var
diff --git a/lib/ecmasys.nim b/lib/system/ecmasys.nim
index e26e763be..c0d0a5fd6 100644
--- a/lib/ecmasys.nim
+++ b/lib/system/ecmasys.nim
@@ -418,7 +418,7 @@ proc internalAssert(file: cstring, line: int) {.pure, compilerproc.} =
 include hti
 
 proc isFatPointer(ti: PNimType): bool =
-  # This has to be consistens with the code generator!
+  # This has to be consistent with the code generator!
   return ti.base.kind notin {tyRecord, tyRecordConstr, tyObject,
     tyArray, tyArrayConstr, tyPureObject, tyTuple,
     tyEmptySet, tyOpenArray, tySet, tyVar, tyRef, tyPtr}
diff --git a/lib/excpt.nim b/lib/system/excpt.nim
index 293491fe9..293491fe9 100644
--- a/lib/excpt.nim
+++ b/lib/system/excpt.nim
diff --git a/lib/gc.nim b/lib/system/gc.nim
index f91b8843e..f91b8843e 100644
--- a/lib/gc.nim
+++ b/lib/system/gc.nim
diff --git a/lib/hti.nim b/lib/system/hti.nim
index 7639cf6a3..dd74bfa3f 100644
--- a/lib/hti.nim
+++ b/lib/system/hti.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
+#        (c) Copyright 2009 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -19,26 +19,27 @@ type # This should be he same as ast.TTypeKind
     tyGeneric, # 6
     tyGenericInst, # 7
     tyGenericParam, # 8
-    tyEnum, # 9
-    tyAnyEnum, # 10
-    tyArray, # 11
-    tyObject, # 12 
-    tyTuple, # 13
-    tySet, # 14
-    tyRange, # 15
-    tyPtr, # 16
-    tyRef, # 17
-    tyVar, # 18
-    tySequence, # 19
-    tyProc, # 20
-    tyPointer, # 21
-    tyOpenArray, # 22
-    tyString, # 23
-    tyCString, # 24
-    tyForward, # 25
+    tyAbstract, # 9
+    tyEnum, # 10
+    tyOrdinal, # 11
+    tyArray, # 12
+    tyObject, # 13 
+    tyTuple, # 14
+    tySet, # 15
+    tyRange, # 16
+    tyPtr, # 17
+    tyRef, # 18
+    tyVar, # 19
+    tySequence, # 20
+    tyProc, # 21
+    tyPointer, # 22
+    tyOpenArray, # 23
+    tyString, # 24
+    tyCString, # 25
+    tyForward, # 26
     tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
     tyFloat, tyFloat32, tyFloat64, tyFloat128,
-    tyPureObject # 35: signals that object has no `n_type` field
+    tyPureObject # 36: signals that object has no `n_type` field
 
   TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
   TNimNode {.compilerproc, final.} = object
diff --git a/lib/mm.nim b/lib/system/mm.nim
index 3bfb8a689..9e207fcf0 100644
--- a/lib/mm.nim
+++ b/lib/system/mm.nim
@@ -128,7 +128,7 @@ when defined(boehmgc):
   proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerproc, inline.} =
     dest^ = src
 
-  include cellsets
+  include "system/cellsets"
 elif defined(nogc):
   proc alloc(size: int): pointer =
     result = c_malloc(size)
@@ -176,12 +176,12 @@ elif defined(nogc):
   proc asgnRefNoCycle(dest: ppointer, src: pointer) {.compilerproc, inline.} =
     dest^ = src
 
-  include cellsets
+  include "system/cellsets"
 else:
-  include alloc
-  include cellsets
+  include "system/alloc"
+  include "system/cellsets"
   assert(sizeof(TCell) == sizeof(TFreeCell))
-  include gc
+  include "system/gc"
   
 {.pop.}
 
diff --git a/lib/profiler.nim b/lib/system/profiler.nim
index 97c7dcfeb..97c7dcfeb 100644
--- a/lib/profiler.nim
+++ b/lib/system/profiler.nim
diff --git a/lib/repr.nim b/lib/system/repr.nim
index 765d66be0..765d66be0 100644
--- a/lib/repr.nim
+++ b/lib/system/repr.nim
diff --git a/lib/sets.nim b/lib/system/sets.nim
index 395a2286c..651cc534b 100644
--- a/lib/sets.nim
+++ b/lib/system/sets.nim
@@ -20,7 +20,7 @@ proc countBits(n: int32): int {.exportc: "countBits".}
 # in math.nim too. So when linking with math.nim it'd give a duplicated
 # symbol error which we avoid by renaming here.
 
-include cntbits
+include "system/cntbits"
 
 proc unionSets(res: var TNimSet, a, b: TNimSet, len: int) {.
     compilerproc, inline.} =
diff --git a/lib/sysio.nim b/lib/system/sysio.nim
index bd52ef5ea..81746c8fb 100644
--- a/lib/sysio.nim
+++ b/lib/system/sysio.nim
@@ -99,10 +99,8 @@ proc writeln[Ty](f: TFile, x: openArray[Ty]) =
   for i in items(x): write(f, i)
   write(f, "\n")
 
-proc echo[Ty](x: Ty) = writeln(stdout, x)
-proc echo[Ty](x: openArray[Ty]) = 
-  for i in items(x): write(stdout, i)
-  write(stdout, "\n")
+proc rawEcho(x: string) {.inline, compilerproc.} = write(stdout, x)
+proc rawEchoNL() {.inline, compilerproc.} = write(stdout, "\n")
 
 # interface to the C procs:
 proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.}
diff --git a/lib/sysstr.nim b/lib/system/sysstr.nim
index 783bce6af..783bce6af 100644
--- a/lib/sysstr.nim
+++ b/lib/system/sysstr.nim
diff --git a/lib/target.h b/lib/target.h
deleted file mode 100644
index 1afd62aef..000000000
--- a/lib/target.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _TARGET_H_
-#define _TARGET_H_
-
-#include <pthread.h>
-
-#define TLSF_MLOCK_T            pthread_mutex_t
-#define TLSF_CREATE_LOCK(l)     pthread_mutex_init (l, NULL)
-#define TLSF_DESTROY_LOCK(l)    pthread_mutex_destroy(l)
-#define TLSF_ACQUIRE_LOCK(l)    pthread_mutex_lock(l)
-#define TLSF_RELEASE_LOCK(l)    pthread_mutex_unlock(l)
-
-#endif
diff --git a/lib/tlsf.c b/lib/tlsf.c
deleted file mode 100644
index 767299ed6..000000000
--- a/lib/tlsf.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/* 
- * Two Levels Segregate Fit memory allocator (TLSF)
- * Version 2.4.3
- *
- * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
- *
- * Thanks to Ismael Ripoll for his suggestions and reviews
- *
- * Copyright (C) 2008, 2007, 2006, 2005, 2004
- *
- * This code is released using a dual license strategy: GPL/LGPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of the GNU General Public License Version 2.0
- * Released under the terms of the GNU Lesser General Public License Version 2.1
- *
- */
-
-/*
- * Code contributions:
- *
- * (Jul 28 2007)  Herman ten Brugge <hermantenbrugge@home.nl>:
- *
- * - Add 64 bit support. It now runs on x86_64 and solaris64.
- * - I also tested this on vxworks/32and solaris/32 and i386/32 processors.
- * - Remove assembly code. I could not measure any performance difference 
- *   on my core2 processor. This also makes the code more portable.
- * - Moved defines/typedefs from tlsf.h to tlsf.c
- * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to 
- *   (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact 
- *    that the minumum size is still sizeof 
- *   (bhdr_t).
- * - Changed all C++ comment style to C style. (// -> /.* ... *./)
- * - Used ls_bit instead of ffs and ms_bit instead of fls. I did this to 
- *   avoid confusion with the standard ffs function which returns 
- *   different values.
- * - Created set_bit/clear_bit fuctions because they are not present 
- *   on x86_64.
- * - Added locking support + extra file target.h to show how to use it.
- * - Added get_used_size function (REMOVED in 2.4)
- * - Added rtl_realloc and rtl_calloc function
- * - Implemented realloc clever support.
- * - Added some test code in the example directory.
- *        
- *
- * (Oct 23 2006) Adam Scislowicz: 
- *
- * - Support for ARMv5 implemented
- *
- */
-
-/************************************************************************/
-
-#define USE_SBRK        (1) 
-#define USE_MMAP        (1) 
-#define TLSF_STATISTIC  (1)
-
-#include <stdio.h>
-#include <string.h>
-
-#ifndef TLSF_USE_LOCKS
-#define  TLSF_USE_LOCKS   (0)
-#endif
-
-#ifndef TLSF_STATISTIC
-#define  TLSF_STATISTIC   (0)
-#endif
-
-#ifndef USE_MMAP
-#define  USE_MMAP   (0)
-#endif
-
-#ifndef USE_SBRK
-#define  USE_SBRK   (0)
-#endif
-
-
-#if TLSF_USE_LOCKS
-#include "target.h"
-#else
-#define TLSF_CREATE_LOCK(_unused_)   do {} while(0)
-#define TLSF_DESTROY_LOCK(_unused_)  do {} while(0) 
-#define TLSF_ACQUIRE_LOCK(_unused_)  do {} while(0)
-#define TLSF_RELEASE_LOCK(_unused_)  do {} while(0)
-#endif
-
-#if TLSF_STATISTIC
-#define  TLSF_ADD_SIZE(tlsf, b) do {                  \
-    tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;  \
-    if (tlsf->used_size > tlsf->max_size)             \
-      tlsf->max_size = tlsf->used_size;            \
-    } while(0)
-
-#define  TLSF_REMOVE_SIZE(tlsf, b) do {                \
-    tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;  \
-  } while(0)
-#else
-#define  TLSF_ADD_SIZE(tlsf, b)       do{}while(0)
-#define  TLSF_REMOVE_SIZE(tlsf, b)    do{}while(0)
-#endif
-
-#if USE_MMAP || USE_SBRK
-#include <unistd.h>
-#endif
-
-#if USE_MMAP
-#include <sys/mman.h>
-#endif
-
-#include "tlsf.h"
-
-#if !defined(__GNUC__)
-#ifndef __inline__
-#define __inline__
-#endif
-#endif
-
-/* The  debug functions  only can  be used  when _DEBUG_TLSF_  is set. */
-#ifndef _DEBUG_TLSF_
-#define _DEBUG_TLSF_  (0)
-#endif
-
-/*************************************************************************/
-/* Definition of the structures used by TLSF */
-
-
-/* Some IMPORTANT TLSF parameters */
-/* Unlike the preview TLSF versions, now they are statics */
-#define BLOCK_ALIGN (sizeof(void *) * 2)
-
-#define MAX_FLI    (30)
-#define MAX_LOG2_SLI  (5)
-#define MAX_SLI    (1 << MAX_LOG2_SLI)     /* MAX_SLI = 2^MAX_LOG2_SLI */
-
-#define FLI_OFFSET  (6)     /* tlsf structure just will manage blocks bigger */
-/* than 128 bytes */
-#define SMALL_BLOCK  (128)
-#define REAL_FLI  (MAX_FLI - FLI_OFFSET)
-#define MIN_BLOCK_SIZE  (sizeof (free_ptr_t))
-#define BHDR_OVERHEAD  (sizeof (bhdr_t) - MIN_BLOCK_SIZE)
-#define TLSF_SIGNATURE  (0x2A59FA59)
-
-#define  PTR_MASK  (sizeof(void *) - 1)
-#define BLOCK_SIZE  (0xFFFFFFFF - PTR_MASK)
-
-#define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r)))
-#define  MEM_ALIGN      ((BLOCK_ALIGN) - 1)
-#define ROUNDUP_SIZE(_r)          (((_r) + MEM_ALIGN) & ~MEM_ALIGN)
-#define ROUNDDOWN_SIZE(_r)        ((_r) & ~MEM_ALIGN)
-#define ROUNDUP(_x, _v)           ((((~(_x)) + 1) & ((_v)-1)) + (_x))
-
-#define BLOCK_STATE  (0x1)
-#define PREV_STATE  (0x2)
-
-/* bit 0 of the block size */
-#define FREE_BLOCK  (0x1)
-#define USED_BLOCK  (0x0)
-
-/* bit 1 of the block size */
-#define PREV_FREE  (0x2)
-#define PREV_USED  (0x0)
-
-
-#define DEFAULT_AREA_SIZE (1024*10)
-
-#ifdef USE_MMAP
-#define PAGE_SIZE (getpagesize())
-#endif
-
-#define PRINT_MSG(fmt, args...) printf(fmt, ## args)
-#define ERROR_MSG(fmt, args...) printf(fmt, ## args)
-
-typedef unsigned int u32_t;     /* NOTE: Make sure that this type is 4 bytes long on your computer */
-typedef unsigned char u8_t;     /* NOTE: Make sure that this type is 1 byte on your computer */
-
-typedef struct free_ptr_struct {
-    struct bhdr_struct *prev;
-    struct bhdr_struct *next;
-} free_ptr_t;
-
-typedef struct bhdr_struct {
-    /* This pointer is just valid if the first bit of size is set */
-    struct bhdr_struct *prev_hdr;
-    /* The size is stored in bytes */
-    size_t size;                /* bit 0 indicates whether the block is used and */
-    /* bit 1 allows to know whether the previous block is free */
-    union {
-        struct free_ptr_struct free_ptr;
-        u8_t buffer[1];         /*sizeof(struct free_ptr_struct)]; */
-    } ptr;
-} bhdr_t;
-
-/* This structure is embedded at the beginning of each area, giving us
- * enough information to cope with a set of areas */
-
-typedef struct area_info_struct {
-    bhdr_t *end;
-    struct area_info_struct *next;
-} area_info_t;
-
-typedef struct TLSF_struct {
-    /* the TLSF's structure signature */
-    u32_t tlsf_signature;
-
-#if TLSF_USE_LOCKS
-    TLSF_MLOCK_T lock;
-#endif
-
-#if TLSF_STATISTIC
-    /* These can not be calculated outside tlsf because we
-     * do not know the sizes when freeing/reallocing memory. */
-    size_t used_size;
-    size_t max_size;
-#endif
-
-    /* A linked list holding all the existing areas */
-    area_info_t *area_head;
-
-    /* the first-level bitmap */
-    /* This array should have a size of REAL_FLI bits */
-    u32_t fl_bitmap;
-
-    /* the second-level bitmap */
-    u32_t sl_bitmap[REAL_FLI];
-
-    bhdr_t *matrix[REAL_FLI][MAX_SLI];
-} tlsf_t;
-
-
-/******************************************************************/
-/**************     Helping functions    **************************/
-/******************************************************************/
-static __inline__ void set_bit(int nr, u32_t * addr);
-static __inline__ void clear_bit(int nr, u32_t * addr);
-static __inline__ int ls_bit(int x);
-static __inline__ int ms_bit(int x);
-static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl);
-static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl);
-static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl);
-static __inline__ bhdr_t *process_area(void *area, size_t size);
-#if USE_SBRK || USE_MMAP
-static __inline__ void *get_new_area(size_t * size);
-#endif
-
-static const int table[] = {
-    -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
-    4, 4,
-    4, 4, 4, 4, 4, 4, 4,
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-    5,
-    5, 5, 5, 5, 5, 5, 5,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    6,
-    6, 6, 6, 6, 6, 6, 6,
-    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-    6,
-    6, 6, 6, 6, 6, 6, 6,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7,
-    7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7,
-    7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7,
-    7, 7, 7, 7, 7, 7, 7,
-    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-    7,
-    7, 7, 7, 7, 7, 7, 7
-};
-
-static __inline__ int ls_bit(int i)
-{
-    unsigned int a;
-    unsigned int x = i & -i;
-
-    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
-    return table[x >> a] + a;
-}
-
-static __inline__ int ms_bit(int i)
-{
-    unsigned int a;
-    unsigned int x = (unsigned int) i;
-
-    a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
-    return table[x >> a] + a;
-}
-
-static __inline__ void set_bit(int nr, u32_t * addr)
-{
-    addr[nr >> 5] |= 1 << (nr & 0x1f);
-}
-
-static __inline__ void clear_bit(int nr, u32_t * addr)
-{
-    addr[nr >> 5] &= ~(1 << (nr & 0x1f));
-}
-
-static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl)
-{
-    int _t;
-
-    if (*_r < SMALL_BLOCK) {
-        *_fl = 0;
-        *_sl = *_r / (SMALL_BLOCK / MAX_SLI);
-    } else {
-        _t = (1 << (ms_bit(*_r) - MAX_LOG2_SLI)) - 1;
-        *_r = *_r + _t;
-        *_fl = ms_bit(*_r);
-        *_sl = (*_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
-        *_fl -= FLI_OFFSET;
-        /*if ((*_fl -= FLI_OFFSET) < 0) // FL wil be always >0!
-         *_fl = *_sl = 0;
-         */
-        *_r &= ~_t;
-    }
-}
-
-static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
-{
-    if (_r < SMALL_BLOCK) {
-        *_fl = 0;
-        *_sl = _r / (SMALL_BLOCK / MAX_SLI);
-    } else {
-        *_fl = ms_bit(_r);
-        *_sl = (_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
-        *_fl -= FLI_OFFSET;
-    }
-}
-
-
-static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl)
-{
-    u32_t _tmp = _tlsf->sl_bitmap[*_fl] & (~0 << *_sl);
-    bhdr_t *_b = NULL;
-
-    if (_tmp) {
-        *_sl = ls_bit(_tmp);
-        _b = _tlsf->matrix[*_fl][*_sl];
-    } else {
-        *_fl = ls_bit(_tlsf->fl_bitmap & (~0 << (*_fl + 1)));
-        if (*_fl > 0) {         /* likely */
-            *_sl = ls_bit(_tlsf->sl_bitmap[*_fl]);
-            _b = _tlsf->matrix[*_fl][*_sl];
-        }
-    }
-    return _b;
-}
-
-
-#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do {          \
-    _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next;    \
-    if (_tlsf -> matrix[_fl][_sl])                \
-      _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL;  \
-    else {                            \
-      clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]);        \
-      if (!_tlsf -> sl_bitmap [_fl])              \
-        clear_bit (_fl, &_tlsf -> fl_bitmap);        \
-    }                              \
-    _b -> ptr.free_ptr.prev =  NULL;        \
-    _b -> ptr.free_ptr.next =  NULL;        \
-  }while(0)
-
-
-#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do {              \
-    if (_b -> ptr.free_ptr.next)                  \
-      _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \
-    if (_b -> ptr.free_ptr.prev)                  \
-      _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \
-    if (_tlsf -> matrix [_fl][_sl] == _b) {              \
-      _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next;    \
-      if (!_tlsf -> matrix [_fl][_sl]) {              \
-        clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]);        \
-        if (!_tlsf -> sl_bitmap [_fl])              \
-          clear_bit (_fl, &_tlsf -> fl_bitmap);        \
-      }                              \
-    }                                \
-    _b -> ptr.free_ptr.prev = NULL;          \
-    _b -> ptr.free_ptr.next = NULL;          \
-  } while(0)
-
-#define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do {              \
-    _b -> ptr.free_ptr.prev = NULL; \
-    _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \
-    if (_tlsf -> matrix [_fl][_sl])                  \
-      _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b;    \
-    _tlsf -> matrix [_fl][_sl] = _b;                \
-    set_bit (_sl, &_tlsf -> sl_bitmap [_fl]);            \
-    set_bit (_fl, &_tlsf -> fl_bitmap);                \
-  } while(0)
-
-#ifndef MAP_ANONYMOUS
-#  ifdef MAP_ANON
-#    define MAP_ANONYMOUS MAP_ANON
-#  else
-#    define MAP_ANONYMOUS 0x20
-#  endif
-#endif
-
-#if USE_SBRK || USE_MMAP
-static __inline__ void *get_new_area(size_t * size) 
-{
-    void *area;
-
-#if USE_SBRK
-    area = (void *)sbrk(0);
-    if (((void *)sbrk(*size)) != ((void *) -1))
-        return area;
-#endif
-
-#if USE_MMAP
-    *size = ROUNDUP(*size, PAGE_SIZE);
-    if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
-        return area;
-#endif
-    return ((void *) ~0);
-}
-#endif
-
-static __inline__ bhdr_t *process_area(void *area, size_t size)
-{
-    bhdr_t *b, *lb, *ib;
-    area_info_t *ai;
-
-    ib = (bhdr_t *) area;
-    ib->size =
-        (sizeof(area_info_t) <
-         MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED;
-    b = (bhdr_t *) GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
-    b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED;
-    b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0;
-    lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-    lb->prev_hdr = b;
-    lb->size = 0 | USED_BLOCK | PREV_FREE;
-    ai = (area_info_t *) ib->ptr.buffer;
-    ai->next = 0;
-    ai->end = lb;
-    return ib;
-}
-
-/******************************************************************/
-/******************** Begin of the allocator code *****************/
-/******************************************************************/
-
-static char *mp = NULL;         /* Default memory pool. */
-
-/******************************************************************/
-size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
-{
-/******************************************************************/
-    tlsf_t *tlsf;
-    bhdr_t *b, *ib;
-
-    if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) {
-        ERROR_MSG("init_memory_pool (): memory_pool invalid\n");
-        return -1;
-    }
-
-    if (((unsigned long) mem_pool & PTR_MASK)) {
-        ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n");
-        return -1;
-    }
-    tlsf = (tlsf_t *) mem_pool;
-    /* Check if already initialised */
-    if (tlsf->tlsf_signature == TLSF_SIGNATURE) {
-        mp = mem_pool;
-        b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t)));
-        return b->size & BLOCK_SIZE;
-    }
-
-    mp = mem_pool;
-
-    /* Zeroing the memory pool */
-    memset(mem_pool, 0, sizeof(tlsf_t));
-
-    tlsf->tlsf_signature = TLSF_SIGNATURE;
-
-    TLSF_CREATE_LOCK(&tlsf->lock);
-
-    ib = process_area(GET_NEXT_BLOCK
-                      (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)));
-    b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
-    free_ex(b->ptr.buffer, tlsf);
-    tlsf->area_head = (area_info_t *) ib->ptr.buffer;
-
-#if TLSF_STATISTIC
-    tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE);
-    tlsf->max_size = tlsf->used_size;
-#endif
-
-    return (b->size & BLOCK_SIZE);
-}
-
-/******************************************************************/
-size_t add_new_area(void *area, size_t area_size, void *mem_pool)
-{
-/******************************************************************/
-    tlsf_t *tlsf = (tlsf_t *) mem_pool;
-    area_info_t *ptr, *ptr_prev, *ai;
-    bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
-
-    memset(area, 0, area_size);
-    ptr = tlsf->area_head;
-    ptr_prev = 0;
-
-    ib0 = process_area(area, area_size);
-    b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE);
-    lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE);
-
-    /* Before inserting the new area, we have to merge this area with the
-       already existing ones */
-
-    while (ptr) {
-        ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
-        b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE);
-        lb1 = ptr->end;
-
-        /* Merging the new area with the next physically contigous one */
-        if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) {
-            if (tlsf->area_head == ptr) {
-                tlsf->area_head = ptr->next;
-                ptr = ptr->next;
-            } else {
-                ptr_prev->next = ptr->next;
-                ptr = ptr->next;
-            }
-
-            b0->size =
-                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
-                               (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED;
-
-            b1->prev_hdr = b0;
-            lb0 = lb1;
-
-            continue;
-        }
-
-        /* Merging the new area with the previous physically contigous
-           one */
-        if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) {
-            if (tlsf->area_head == ptr) {
-                tlsf->area_head = ptr->next;
-                ptr = ptr->next;
-            } else {
-                ptr_prev->next = ptr->next;
-                ptr = ptr->next;
-            }
-
-            lb1->size =
-                ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
-                               (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE);
-            next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE);
-            next_b->prev_hdr = lb1;
-            b0 = lb1;
-            ib0 = ib1;
-
-            continue;
-        }
-        ptr_prev = ptr;
-        ptr = ptr->next;
-    }
-
-    /* Inserting the area in the list of linked areas */
-    ai = (area_info_t *) ib0->ptr.buffer;
-    ai->next = tlsf->area_head;
-    ai->end = lb0;
-    tlsf->area_head = ai;
-    free_ex(b0->ptr.buffer, mem_pool);
-    return (b0->size & BLOCK_SIZE);
-}
-
-
-/******************************************************************/
-size_t get_used_size(void *mem_pool)
-{
-/******************************************************************/
-#if TLSF_STATISTIC
-    return ((tlsf_t *) mem_pool)->used_size;
-#else
-    return 0;
-#endif
-}
-
-/******************************************************************/
-size_t get_max_size(void *mem_pool)
-{
-/******************************************************************/
-#if TLSF_STATISTIC
-    return ((tlsf_t *) mem_pool)->max_size;
-#else
-    return 0;
-#endif
-}
-
-/******************************************************************/
-void destroy_memory_pool(void *mem_pool)
-{
-/******************************************************************/
-    tlsf_t *tlsf = (tlsf_t *) mem_pool;
-
-    tlsf->tlsf_signature = 0;
-
-    TLSF_DESTROY_LOCK(&tlsf->lock);
-
-}
-
-
-/******************************************************************/
-void *tlsf_malloc(size_t size)
-{
-/******************************************************************/
-    void *ret;
-
-#if USE_MMAP || USE_SBRK
-    if (!mp) {
-        size_t area_size;
-        void *area;
-
-        area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */
-        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
-        area = get_new_area(&area_size);
-        if (area == ((void *) ~0))
-            return NULL;        /* Not enough system memory */
-        init_memory_pool(area_size, area);
-    }
-#endif
-
-    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
-
-    ret = malloc_ex(size, mp);
-
-    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
-
-    return ret;
-}
-
-/******************************************************************/
-void tlsf_free(void *ptr)
-{
-/******************************************************************/
-
-    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
-
-    free_ex(ptr, mp);
-
-    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
-
-}
-
-/******************************************************************/
-void *tlsf_realloc(void *ptr, size_t size)
-{
-/******************************************************************/
-    void *ret;
-
-#if USE_MMAP || USE_SBRK
-  if (!mp) {
-    return tlsf_malloc(size);
-  }
-#endif
-
-    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
-
-    ret = realloc_ex(ptr, size, mp);
-
-    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
-
-    return ret;
-}
-
-/******************************************************************/
-void *tlsf_calloc(size_t nelem, size_t elem_size)
-{
-/******************************************************************/
-    void *ret;
-
-    TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
-
-    ret = calloc_ex(nelem, elem_size, mp);
-
-    TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
-
-    return ret;
-}
-
-/******************************************************************/
-void *malloc_ex(size_t size, void *mem_pool)
-{
-/******************************************************************/
-    tlsf_t *tlsf = (tlsf_t *) mem_pool;
-    bhdr_t *b, *b2, *next_b;
-    int fl, sl;
-    size_t tmp_size;
-
-    size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
-
-    /* Rounding up the requested size and calculating fl and sl */
-    MAPPING_SEARCH(&size, &fl, &sl);
-
-    /* Searching a free block, recall that this function changes the values of fl and sl,
-       so they are not longer valid when the function fails */
-    b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
-#if USE_MMAP || USE_SBRK
-    if (!b) {
-        size_t area_size;
-        void *area;
-        /* Growing the pool size when needed */
-        area_size = size + BHDR_OVERHEAD * 8;   /* size plus enough room for the requered headers. */
-        area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
-        area = get_new_area(&area_size);        /* Call sbrk or mmap */
-        if (area == ((void *) ~0))
-            return NULL;        /* Not enough system memory */
-        add_new_area(area, area_size, mem_pool);
-        /* Rounding up the requested size and calculating fl and sl */
-        MAPPING_SEARCH(&size, &fl, &sl);
-        /* Searching a free block */
-        b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
-    }
-#endif
-    if (!b)
-        return NULL;            /* Not found */
-
-    EXTRACT_BLOCK_HDR(b, tlsf, fl, sl);
-
-    /*-- found: */
-    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-    /* Should the block be split? */
-    tmp_size = (b->size & BLOCK_SIZE) - size;
-    if (tmp_size >= sizeof(bhdr_t)) {
-        tmp_size -= BHDR_OVERHEAD;
-        b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
-        b2->size = tmp_size | FREE_BLOCK | PREV_USED;
-        next_b->prev_hdr = b2;
-        MAPPING_INSERT(tmp_size, &fl, &sl);
-        INSERT_BLOCK(b2, tlsf, fl, sl);
-
-        b->size = size | (b->size & PREV_STATE);
-    } else {
-        next_b->size &= (~PREV_FREE);
-        b->size &= (~FREE_BLOCK);       /* Now it's used */
-    }
-
-    TLSF_ADD_SIZE(tlsf, b);
-
-    return (void *) b->ptr.buffer;
-}
-
-extern void free_ex(void *ptr, void *mem_pool) {
-    tlsf_t *tlsf = (tlsf_t *) mem_pool;
-    bhdr_t *b, *tmp_b;
-    int fl = 0, sl = 0;
-
-    if (!ptr) {
-        return;
-    }
-    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
-    b->size |= FREE_BLOCK;
-
-    TLSF_REMOVE_SIZE(tlsf, b);
-
-    b->ptr.free_ptr.prev = NULL;
-    b->ptr.free_ptr.next = NULL;
-    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-    if (tmp_b->size & FREE_BLOCK) {
-        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
-        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
-        b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
-    }
-    if (b->size & PREV_FREE) {
-        tmp_b = b->prev_hdr;
-        MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
-        EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
-        tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
-        b = tmp_b;
-    }
-    MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl);
-    INSERT_BLOCK(b, tlsf, fl, sl);
-
-    tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-    tmp_b->size |= PREV_FREE;
-    tmp_b->prev_hdr = b;
-}
-
-/******************************************************************/
-void *realloc_ex(void *ptr, size_t new_size, void *mem_pool)
-{
-/******************************************************************/
-    tlsf_t *tlsf = (tlsf_t *) mem_pool;
-    void *ptr_aux;
-    unsigned int cpsize;
-    bhdr_t *b, *tmp_b, *next_b;
-    int fl, sl;
-    size_t tmp_size;
-
-    if (!ptr) {
-        if (new_size)
-            return (void *) malloc_ex(new_size, mem_pool);
-        if (!new_size)
-            return NULL;
-    } else if (!new_size) {
-        free_ex(ptr, mem_pool);
-        return NULL;
-    }
-
-    b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
-    next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-    new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size);
-    tmp_size = (b->size & BLOCK_SIZE);
-    if (new_size <= tmp_size) {
-        TLSF_REMOVE_SIZE(tlsf, b);
-        if (next_b->size & FREE_BLOCK) {
-            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
-            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
-            tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
-            next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE);
-            /* We allways reenter this free block because tmp_size will
-               be greater then sizeof (bhdr_t) */
-        }
-        tmp_size -= new_size;
-        if (tmp_size >= sizeof(bhdr_t)) {
-            tmp_size -= BHDR_OVERHEAD;
-            tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
-            tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
-            next_b->prev_hdr = tmp_b;
-            next_b->size |= PREV_FREE;
-            MAPPING_INSERT(tmp_size, &fl, &sl);
-            INSERT_BLOCK(tmp_b, tlsf, fl, sl);
-            b->size = new_size | (b->size & PREV_STATE);
-        }
-        TLSF_ADD_SIZE(tlsf, b);
-        return (void *) b->ptr.buffer;
-    }
-    if ((next_b->size & FREE_BLOCK)) {
-        if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) {
-            TLSF_REMOVE_SIZE(tlsf, b);
-            MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
-            EXTRACT_BLOCK(next_b, tlsf, fl, sl);
-            b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
-            next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
-            next_b->prev_hdr = b;
-            next_b->size &= ~PREV_FREE;
-            tmp_size = (b->size & BLOCK_SIZE) - new_size;
-            if (tmp_size >= sizeof(bhdr_t)) {
-                tmp_size -= BHDR_OVERHEAD;
-                tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
-                tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
-                next_b->prev_hdr = tmp_b;
-                next_b->size |= PREV_FREE;
-                MAPPING_INSERT(tmp_size, &fl, &sl);
-                INSERT_BLOCK(tmp_b, tlsf, fl, sl);
-                b->size = new_size | (b->size & PREV_STATE);
-            }
-            TLSF_ADD_SIZE(tlsf, b);
-            return (void *) b->ptr.buffer;
-        }
-    }
-
-    ptr_aux = malloc_ex(new_size, mem_pool);
-
-    cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE);
-
-    memcpy(ptr_aux, ptr, cpsize);
-
-    free_ex(ptr, mem_pool);
-    return ptr_aux;
-}
-
-
-/******************************************************************/
-void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
-{
-/******************************************************************/
-    void *ptr;
-
-    if (nelem <= 0 || elem_size <= 0)
-        return NULL;
-
-    if (!(ptr = malloc_ex(nelem * elem_size, mem_pool)))
-        return NULL;
-    memset(ptr, 0, nelem * elem_size);
-
-    return ptr;
-}
-
-/* for Nimrod: */
-size_t TLSF_GET_USED_SIZE(void) { return (((tlsf_t *)mp)->used_size); }
-size_t TLSF_GET_MAX_SIZE(void) { return (((tlsf_t *)mp)->max_size); }
-
-
-#if _DEBUG_TLSF_
-
-/***************  DEBUG FUNCTIONS   **************/
-
-/* The following functions have been designed to ease the debugging of */
-/* the TLSF  structure.  For non-developing  purposes, it may  be they */
-/* haven't too much worth.  To enable them, _DEBUG_TLSF_ must be set.  */
-
-extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size);
-extern void print_block(bhdr_t * b);
-extern void print_tlsf(tlsf_t * tlsf);
-void print_all_blocks(tlsf_t * tlsf);
-
-void dump_memory_region(unsigned char *mem_ptr, unsigned int size)
-{
-
-    unsigned long begin = (unsigned long) mem_ptr;
-    unsigned long end = (unsigned long) mem_ptr + size;
-    int column = 0;
-
-    begin >>= 2;
-    begin <<= 2;
-
-    end >>= 2;
-    end++;
-    end <<= 2;
-
-    PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
-
-    column = 0;
-    PRINT_MSG("0x%lx ", begin);
-
-    while (begin < end) {
-        if (((unsigned char *) begin)[0] == 0)
-            PRINT_MSG("00");
-        else
-            PRINT_MSG("%02x", ((unsigned char *) begin)[0]);
-        if (((unsigned char *) begin)[1] == 0)
-            PRINT_MSG("00 ");
-        else
-            PRINT_MSG("%02x ", ((unsigned char *) begin)[1]);
-        begin += 2;
-        column++;
-        if (column == 8) {
-            PRINT_MSG("\n0x%lx ", begin);
-            column = 0;
-        }
-
-    }
-    PRINT_MSG("\n\n");
-}
-
-void print_block(bhdr_t * b)
-{
-    if (!b)
-        return;
-    PRINT_MSG(">> [%p] (", b);
-    if ((b->size & BLOCK_SIZE))
-        PRINT_MSG("%lu bytes, ", (unsigned long) (b->size & BLOCK_SIZE));
-    else
-        PRINT_MSG("sentinel, ");
-    if ((b->size & BLOCK_STATE) == FREE_BLOCK)
-        PRINT_MSG("free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next);
-    else
-        PRINT_MSG("used, ");
-    if ((b->size & PREV_STATE) == PREV_FREE)
-        PRINT_MSG("prev. free [%p])\n", b->prev_hdr);
-    else
-        PRINT_MSG("prev used)\n");
-}
-
-void print_tlsf(tlsf_t * tlsf)
-{
-    bhdr_t *next;
-    int i, j;
-
-    PRINT_MSG("\nTLSF at %p\n", tlsf);
-
-    PRINT_MSG("FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap);
-
-    for (i = 0; i < REAL_FLI; i++) {
-        if (tlsf->sl_bitmap[i])
-            PRINT_MSG("SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]);
-        for (j = 0; j < MAX_SLI; j++) {
-            next = tlsf->matrix[i][j];
-            if (next)
-                PRINT_MSG("-> [%d][%d]\n", i, j);
-            while (next) {
-                print_block(next);
-                next = next->ptr.free_ptr.next;
-            }
-        }
-    }
-}
-
-void print_all_blocks(tlsf_t * tlsf)
-{
-    area_info_t *ai;
-    bhdr_t *next;
-    PRINT_MSG("\nTLSF at %p\nALL BLOCKS\n\n", tlsf);
-    ai = tlsf->area_head;
-    while (ai) {
-        next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD);
-        while (next) {
-            print_block(next);
-            if ((next->size & BLOCK_SIZE))
-                next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE);
-            else
-                next = NULL;
-        }
-        ai = ai->next;
-    }
-}
-
-#endif
diff --git a/lib/tlsf.h b/lib/tlsf.h
deleted file mode 100644
index 7c8e2ad66..000000000
--- a/lib/tlsf.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Two Levels Segregate Fit memory allocator (TLSF)
- * Version 2.4.3
- *
- * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
- *
- * Thanks to Ismael Ripoll for his suggestions and reviews
- *
- * Copyright (C) 2008, 2007, 2006, 2005, 2004
- *
- * This code is released using a dual license strategy: GPL/LGPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of the GNU General Public License Version 2.0
- * Released under the terms of the GNU Lesser General Public License Version 2.1
- *
- */
-
-#ifndef _TLSF_H_
-#define _TLSF_H_
-
-#include <sys/types.h>
-
-extern size_t init_memory_pool(size_t, void *);
-extern size_t get_used_size(void *);
-extern size_t get_max_size(void *);
-extern void destroy_memory_pool(void *);
-extern size_t add_new_area(void *, size_t, void *);
-extern void *malloc_ex(size_t, void *);
-extern void free_ex(void *, void *);
-extern void *realloc_ex(void *, size_t, void *);
-extern void *calloc_ex(size_t, size_t, void *);
-
-extern void *tlsf_malloc(size_t size);
-extern void tlsf_free(void *ptr);
-extern void *tlsf_realloc(void *ptr, size_t size);
-extern void *tlsf_calloc(size_t nelem, size_t elem_size);
-
-#endif
diff --git a/lib/tlsfnim.nim b/lib/tlsfnim.nim
deleted file mode 100644
index 249607e2d..000000000
--- a/lib/tlsfnim.nim
+++ /dev/null
@@ -1,698 +0,0 @@
-#
-#
-#            Nimrod's Runtime Library
-#        (c) Copyright 2008 Andreas Rumpf
-#
-#    See the file "copying.txt", included in this
-#    distribution, for details about the copyright.
-#
-
-
-# Memory manager. Based on:
-# Two Levels Segregate Fit memory allocator (TLSF)
-# Version 2.4.2
-#
-# Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
-#
-# Thanks to Ismael Ripoll for his suggestions and reviews
-#
-# Copyright (C) 2008, 2007, 2006, 2005, 2004
-# 
-# This code is released using a dual license strategy: GPL/LGPL
-# You can choose the licence that better fits your requirements.
-# 
-# Released under the terms of the GNU General Public License Version 2.0
-# Released under the terms of the GNU Lesser General Public License Version 2.1
-
-
-# Some IMPORTANT TLSF parameters
-const
-  blockAlign = sizeof(pointer) * 2
-  maxFli = 30
-  maxLog2Sli = 5
-  maxSli = 1 shl maxLog2Sli
-  
-  fliOffset = 6 # tlsf structure just will manage blocks bigger than 128 bytes
-  smallBlock = 128
-  realFli = MaxFli - fliOffset
-  
-type
-  TFreePtr {.final.} = object
-    prev, next: PBhdr
-  Pbhdr = ptr Tbhdr
-  Tbhdr {.final.} = object
-    prevHdr: Pbhdr # this is just valid if the first bit of size is set
-    size: int # the size is stored in bytes 
-              # bit 0 indicates whether the block is used and
-              # bit 1 allows to know whether the previous block is free
-    freePtr: TFreePtr # at this offset bhdr.buffer starts (was a union in the
-                      # C version)
-  TAreaInfo  {.final.} = object  # This structure is embedded at the beginning
-                                 # of each area, giving us enough information 
-                                 # to cope with a set of areas
-    theEnd: Pbhdr
-    next: PAreaInfo
-  PAreaInfo = ptr TAreaInfo
-
-  TLSF {.final.} = object
-    tlsf_signature: int32 # the TLSF's structure signature
-    usedSize, maxSize: int
-    areaHead: PAreaInfo # A linked list holding all the existing areas
-
-    flBitmap: int32  # the first-level bitmap
-                     # This array should have a size of REAL_FLI bits
-    slBitmap: array[0..realFli, int32] # the second-level bitmap
-    matrix: array [0..realFli, array[0..maxSli, PBhdr]]
-  
-const
-  minBlockSize = sizeof(TFreePtr)
-  bhdrOverhead = sizeof(Tbhdr) - minBlockSize
-  tlsfSignature = 0x2A59FA59
-  ptrMask = sizeof(pointer) - 1
-  blockSize = 0xFFFFFFFF - ptrMask
-  memAlign = blockAlign - 1
-  blockState = 0x1
-  prevState = 0x2
-
-  freeBlock = 0x1 # bit 0 of the block size
-  usedBlock = 0x0
-
-  prevFree = 0x2 # bit 1 of the block size
-  prevUsed = 0x0
-  
-  defaultAreaSize = 64*1024 # 1024*10
-  pageSize = if defined(cpu32): 4096 else: 4096*2
-  
-
-proc getNextBlock(adr: pointer, r: int): PBhdr {.inline.} = 
-  return cast[PBhdr](cast[TAddress](adr) +% r)
-
-proc roundupSize(r: int): int = return (r +% memAlign) and not memAlign
-proc rounddownSize(r: int): int = return r and not memAlign
-proc roundup(x, v: int): int = return (((not x)+%1) and (v-%1)) +% x
-
-proc addSize(s: PTLSF, b: Pbhdr) =
-  inc(s.usedSize, (b.size and blockSize) + bhdrOverhead)
-  s.maxSize = max(s.maxSize, s.usedSize)
-
-proc removeSize(s: PTLSF, b: Pbhdr) =
-  dec(s.usedSize, (b.size and blockSize) + bhdrOverhead)
-
-# ------------ platform specific code -----------------------------------------
-
-when defined(posix): 
-  const # XXX: make these variables for portability?
-    PROT_READ  = 1             # page can be read 
-    PROT_WRITE = 2             # page can be written 
-    PROT_EXEC  = 4             # page can be executed 
-    PROT_NONE  = 0             # page can not be accessed 
-
-    MAP_SHARED    = 1          # Share changes 
-    MAP_PRIVATE   = 2          # Changes are private 
-    MAP_TYPE      = 0xf        # Mask for type of mapping 
-    MAP_FIXED     = 0x10       # Interpret addr exactly 
-    MAP_ANONYMOUS = 0x20       # don't use a file 
-
-    MAP_GROWSDOWN  = 0x100     # stack-like segment 
-    MAP_DENYWRITE  = 0x800     # ETXTBSY 
-    MAP_EXECUTABLE = 0x1000    # mark it as an executable 
-    MAP_LOCKED     = 0x2000    # pages are locked 
-    MAP_NORESERVE  = 0x4000    # don't check for reservations 
-
-  proc mmap(adr: pointer, len: int, prot, flags, fildes: cint,
-            off: int): pointer {.header: "<sys/mman.h>".}
-
-  proc getNewArea(size: var int): pointer {.inline.} = 
-    size = roundup(size, PageSize)
-    result = mmap(0, size, PROT_READ or PROT_WRITE, 
-                           MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
-    if result == nil or result == cast[pointer](-1):
-      raiseOutOfMem()
-  
-elif defined(windows): 
-  const
-    MEM_RESERVE = 0x2000 
-    MEM_COMMIT = 0x1000
-    MEM_TOP_DOWN = 0x100000
-    PAGE_READWRITE = 0x04
-
-  proc VirtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType,
-                    flProtect: int32): pointer {.
-                    header: "<windows.h>", stdcall.}
-  
-  proc getNewArea(size: var int): pointer {.inline.} = 
-    size = roundup(size, PageSize)
-    result = VirtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT or MEM_TOP_DOWN,
-                          PAGE_READWRITE)
-    if result == nil: raiseOutOfMem()
-
-else: 
-  {.warning: "Generic code for allocating pages is used".}
-  # generic implementation relying on malloc:
-  proc malloc(size: int): pointer {.nodecl, importc.}
-  
-  proc getNewArea(size: var int): pointer {.inline.} = 
-    size = roundup(size, PageSize)
-    result = malloc(size)
-    if result == nil: raiseOutOfMem()
-
-# ---------------------------------------------------------------------------
-# small fixed size allocator:
-
-# Design: We manage pages. A page is of constant size, but not necessarily
-# the OS's page size. Pages are managed in a hash table taking advantage of
-# the fact that the OS is likely to give us pages with contingous numbers. 
-# A page contains either small fixed size objects of the same size or 
-# variable length objects. An object's size is always aligned at 16 byte
-# boundary. Huge objects are dealt with the TLSF algorithm. 
-# The design supports iterating over any object in a fast way. 
-
-# A bitset contains any page that starts an allocated page. The page may be
-# empty however. This bitset can be used to quickly determine if a given
-# page belongs to the GC heap. The design of the memory allocator makes it 
-# simple to return unused pages back to the OS.
-
-
-# Small bocks 
-# -----------
-#
-# If we use a list in the free object's space. Allocation and deallocation are
-# O(1). Since any object is of the same size, iteration is quite efficient too.
-# However, pointer detection is easy too: Just check if the type-field is nil.
-# Deallocation sets it to nil.
-# Algorithm:
-
-# i = 0
-# f = b.f # first free address
-# while i < max: 
-#  if a[i] == f: # not a valid block
-#    f = f.next  # next free address
-#  else:
-#    a[i] is a valid object of size s
-#  inc(i)
-
-# The zero count table is an array. Since we know that the RC is zero, we can
-# use the bits for an index into this array. Thus multiple ZCT tables are not
-# difficult to support and insertion and removal is O(1). We use negative
-# indexes for this. This makes it even fast enough (and necessary!) to do a ZCT
-# removal if the RC is incremented. 
-# 
-
-# Huge blocks
-# -----------
-#
-# Huge blocks are always rounded up to a multiple of the page size. These are
-# called *strides*. We also need to keep an index structure 
-# of (stridesize, pagelist). 
-# 
-
-const
-  MemAlign = 8
-  PageShift = if sizeof(int) == 4: 12 else: 13
-  PageSize = 1 shl PageShift
-type
-  TFreeList {.final.} = object
-    next, prev: ptr TFreeList
-
-  TPageDesc {.final.} = object  # the start of a stride always starts with this!
-    size: int                   # lowest bit is set, if it is a huge block
-    free: ptr TFreeList         # only used if it manages multiple cells
-    snext, sprev: ptr TPageDesc # next and prev pagedescs with the same size
-
-  TCellArray {.final.} = object
-    i: int # length
-    d: ptr array [0..1000_000, TCell]
-
-  TPageManager = table[page, ptr TPageDesc]
-
-  TGcHeap {.final.} = object
-    # structure that manages the garbage collected heap
-    zct: TCellArray
-    stackCells: TCellArray
-    smallBlocks: array [PageSize div MemAlign, ptr TPageDesc]
-    freeLists: array [PageSize div MemAlign, ptr TFreeList]
-    pages: TPageManager
-    usedPages: TPageList
-    freePages: TPageList
-
-# small blocks: 
-proc allocSmall(var h: TGcHeap, size: int): pointer = 
-  var s = align(size)
-  var f = h.freeLists[s]
-  if f != nil: 
-    f.prev = f.next # remove from list
-    f.next.prev = f.prev
-    return f
-  var p = h.smallBlocks[s]
-  if p == nil or p.free == nil:
-    p = newSmallBlock(s, p)
-    h.smallBlocks[s] = p
-  
-
-
-proc decRef(cell: PCell) {.inline.} =
-  assert(cell in ct.AT)
-  assert(cell.refcount > 0) # this should be the case!
-  assert(seqCheck(cell))
-  dec(cell.refcount)
-  if cell.refcount == 0:
-    # add to zero count table:
-    zct.d[zct.i] = cell
-    cell.recfcount = -zct.i
-    inc(zct.i)
-
-proc incRef(cell: PCell) {.inline.} =
-  assert(seqCheck(cell))
-  if cell.refcount < 0: 
-    # remove from zero count table:
-    zct.d[-cell.refcount] = zct.d[zct.i-1]
-    dec(zct.i) 
-    cell.refcount = 1
-  else:
-    inc(cell.refcount)
-
-proc asgnRef(dest: ppointer, src: pointer) =
-  # the code generator calls this proc!
-  assert(not isOnStack(dest))
-  # BUGFIX: first incRef then decRef!
-  if src != nil: incRef(usrToCell(src))
-  if dest^ != nil: decRef(usrToCell(dest^))
-  dest^ = src
-
-
-# ----------------------------------------------------------------------------
-#     helpers
-
-const
-  table: array[0..255, int8] = [
-      -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
-      4, 4, 4, 4, 4, 4, 4, 4, 4,
-      5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-      5, 5, 5, 5, 5, 5, 5, 5,
-      6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-      6, 6, 6, 6, 6, 6, 6, 6,
-      6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-      6, 6, 6, 6, 6, 6, 6, 6,
-      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-      7, 7, 7, 7, 7, 7, 7, 7
-    ]
-
-proc ls_bit(i: int32): int {.inline.} = 
-  var 
-    a: int = 0
-    x: int = i and -i
-  if x <=% 0xffff:
-    if x <=% ff: a = 0
-    else: a = 8
-  elif x <=% 0xffffff: a = 16
-  else: a = 24
-  return table[x shr a] + a
-
-proc ms_bit(i: int): int {.inline.} = 
-  var
-    a = if i <=% 0xffff: (if i <=% 0xff: 0 else: 8) elif 
-           i <=% 0xffffff: 16 else: 24
-  return table[i shr a] + a
-
-proc set_bit[IX](nr: int, adr: var array[IX, int32]) {.inline.} =
-  adr[nr shr 5] = adr[nr shr 5] or (1 shl (nr and 0x1f))
-
-proc clear_bit[IX](nr: int, adr: var array[IX, int32]) {.inline.} =
-  adr[nr shr 5] = adr[nr shr 5] and not (1 shl (nr and 0x1f))
-
-proc mappingSearch(r, fl, sl: var int) {.inline.} = 
-  if r < smallBlock: 
-    fl = 0
-    sl = r div (smallBlock div maxSli)
-  else:
-    var t = (1 shl (ms_bit(r) - maxLog2Sli)) - 1
-    r = r + t
-    fl = ms_bit(r)
-    sl = (r shl (fl - maxLog2Sli)) - maxSli
-    fl = fl - fliOffset
-    r = r and not t
-
-proc mappingInsert(r: int, fl, sl: var int) {.inline.} = 
-  if r < smallBlock:
-    fl = 0
-    sl = r div (smallBlock div maxSli)
-  else:
-    fl = ms_bit(r)
-    sl = (r shr (fl - maxLog2Sli)) - maxSli
-    fl = fl - fliOffset
-
-proc findSuitableBlock(t: var TLSF, fl, sl: var int): Pbhdr =
-  var tmp = t.slBitmap[fl] and ((not 0) shl sl)
-  if tmp != 0:
-    sl = ls_bit(tmp)
-    result = t.matrix[fl][sl]
-  else:
-    fl = ls_bit(t.flBitmap and (not 0 shl (fl + 1)))
-    if fl > 0: # likely
-      sl = ls_bit(t.slBitmap[fl])
-      result = t.matrix[fl][sl]
-
-proc extractBlockHdr(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} = 
-  t.matrix[fl][sl] = b.freePtr.next
-  if t.matrix[fl][sl] != nil:
-    t.matrix[fl][sl].freePtr.prev = nil
-  else:
-    clear_bit(sl, t.slBitmap[fl])
-    if t.slBitmap[fl] == 0:
-      clear_bit(fl, t.flBitmap)
-  b.freePtr.prev = nil
-  b.freePtr.next = nil
-
-proc extractBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
-  if b.freePtr.next != nil:
-    b.freePtr.next.freePtr.prev = b.freePtr.prev
-  if b.freePtr.prev != nil:
-    b.freePtr.prev.freePtr.next = b.freePtr.next
-  if t.matrix[fl][sl] == b:
-    t.matrix[fl][sl] = b.freePtr.next
-    if t.matrix[fl][sl] == nil:
-      clear_bit(sl, t.slBitmap[fl])
-      if t.slBitmap[fl] == 0:
-        clear_bit(fl, t.flBitmap)
-  b.freePtr.prev = nil
-  b.freePtr.next = nil
-
-proc insertBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} = 
-  b.freePtr.prev = nil
-  b.freePtr.next = t.matrix[fl][sl] 
-  if t.matrix[fl][sl] != nil:
-    t.matrix[fl][sl].freePtr.prev = b		
-  t.matrix[fl][sl] = b
-  set_bit(sl, t.slBitmap[fl])
-  set_bit(fl, t.flBitmap)
-
-proc getBuffer(b: Pbhdr): pointer {.inline.} = 
-  result = cast[pointer](addr(b.freePtr))
-
-proc processArea(area: pointer, size: int): Pbhdr =
-  var 
-    b, lb, ib: Pbhdr
-    ai: PAreaInfo
-  ib = cast[Pbhdr](area)
-  if sizeof(TAreaInfo) < minBlockSize:
-    ib.size = minBlockSize or usedBlock or prevUsed
-  else
-    ib.size = roundupSize(sizeof(TAreaInfo)) or usedBlock or prevUsed
-  b = getNextBlock(getBuffer(ib), ib.size and blockSize)
-  b.size = rounddownSize(size - 3 * bhdrOverhead - (ib.size and blockSize)) or
-           usedBlock or prevUsed
-  b.freePtr.prev = nil
-  b.freePtr.next = nil
-  lb = getNextBlock(getBuffer(b), b.size and blockSize)
-  lb.prevHdr = b
-  lb.size = 0 or usedBlock or prevFree
-  ai = cast[PAreaInfo](getBuffer(ib))
-  ai.next = nil
-  ai.theEnd = lb
-  return ib
-
-# ----------------------------------------------------------------------------
-#                  Begin of the allocator code
-
-proc initMemoryPool(memPoolSize: int, memPool: pointer): int = 
-  var
-    t: PLSF
-    b, ib: Pbhdr
-
-  if memPool == nil or memPoolSize < sizeof(TLSF) + bhdrOverhead * 8:
-    writeToStdErr("initMemoryPool(): memory_pool invalid\n")
-    return -1
-
-  if (cast[TAddress](memPool) and ptrMask) != 0:
-    writeToStdErr("initMemoryPool(): memPool must be aligned to a word\n")
-    return -1
-  t = cast[PLSF](memPool)
-  # Check if already initialised
-  if t.signature == tlsfSignature:
-    b = getNextBlock(memPool, roundupSize(sizeof(TLSF)))
-    return b.size and blockSize
-  zeroMem(memPool, sizeof(TLSF))
-
-  t.signature = tlsfSignature
-  ib = processArea(getNextBlock(memPool, roundupSize(sizeof(TLSF))), 
-                   rounddownSize(memPoolSize - sizeof(TLSF)))
-  b = getNextBlock(getBuffer(ib), ib.size and blockSize)
-  freeEx(getBuffer(b), t)
-  t.areaHead = cast[PAreaInfo](getBuffer(ib))
-
-  t.used_size = memPoolSize - (b.size and blockSize)
-  t.max_size = t.used_size
-  return b.size and blockSize
-
-
-proc addNewArea(area: pointer, areaSize: int, t: var TLSF): int = 
-  var
-    p, ptrPrev, ai: PAreaInfo
-    ib0, b0, lb0, ib1, b1, lb1, nextB: Pbhdr
-
-  zeroMem(area, areaSize)
-  p = t.areaHead
-  ptrPrev = 0
-
-  ib0 = processArea(area, areaSize)
-  b0 = getNextBlock(getBuffer(ib0), ib0.size and blockSize)
-  lb0 = getNextBlock(getBuffer(b0), b0.size and blockSize)
-
-  # Before inserting the new area, we have to merge this area with the
-  # already existing ones
-  while p != nil:
-    ib1 = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead) 
-    b1 = getNextBlock(getBuffer(ib1), ib1.size and blockSize)
-    lb1 = p.theEnd
-
-    # Merging the new area with the next physically contigous one
-    if cast[TAddress](ib1) == cast[TAddress](lb0) +% bhdrOverhead:
-      if t.areaHead == p:
-        t.areaHead = p.next
-        p = p.next
-      else:
-        ptrPrev.next = p.next
-        p = p.next
-      b0.size = rounddownSize((b0.size and blockSize) +
-                         (ib1.size and blockSize) + 2 * bhdrOverhead) or
-                         usedBlock or prevUsed
-      b1.prevHdr = b0
-      lb0 = lb1
-      continue
-
-    # Merging the new area with the previous physically contigous one
-    if getBuffer(lb1) == pointer(ib0):
-      if t.areaHead == p:
-        t.areaHead = p.next
-        p = p.next
-      else:
-        ptrPrev.next = p.next
-        p = p.next
-      lb1->size = rounddownSize((b0.size and blockSize) +
-                   (ib0.size and blockSize) + 2 * bhdrOverhead) or
-                   usedBlock or (lb1.size and prevState)
-      nextB = getNextBlock(getBuffer(lb1), lb1.size and blockSize)
-      nextB.prevHdr = lb1
-      b0 = lb1
-      ib0 = ib1
-      continue
-    ptrPrev = p
-    p = p.next
-
-  # Inserting the area in the list of linked areas 
-  ai = cast[PAreaInfo](getBuffer(ib0))
-  ai.next = t.areaHead
-  ai.theEnd = lb0
-  t.areaHead = ai
-  freeEx(getBuffer(b0), memPool)
-  return (b0.size and blockSize)
-
-proc mallocEx(asize: int, t: var TLSF): pointer = 
-  var
-    b, b2, nextB: Pbhdr
-    fl, sl, tmpSize, size: int
-
-  size = if asize < minBlockSize: minBlockSize else: roundupSize(asize)
-
-  # Rounding up the requested size and calculating fl and sl
-  mappingSearch(size, fl, sl)
-
-  # Searching a free block, recall that this function changes the values
-  # of fl and sl, so they are not longer valid when the function fails
-  b = findSuitableBlock(tlsf, fl, sl)
-  if b == nil: 
-    # Growing the pool size when needed 
-    # size plus enough room for the required headers:
-    var areaSize = max(size + bhdrOverhead * 8, defaultAreaSize)
-    var area = getNewArea(areaSize)
-    addNewArea(area, areaSize, t)
-    # Rounding up the requested size and calculating fl and sl
-    mappingSearch(size, fl, sl)
-    # Searching a free block
-    b = findSuitableBlock(t, fl, sl)
-    if b == nil: 
-      raiseOutOfMem()
-
-  extractBlockHdr(b, t, fl, sl)
-
-  #-- found:
-  nextB = getNextBlock(getBuffer(b), b.size and blockSize)
-  # Should the block be split?
-  tmpSize = (b.size and blockSize) - size
-  if tmpSize >= sizeof(Tbhdr):
-    dec(tmpSize, bhdrOverhead)
-    b2 = getNextBlock(getBuffer(b), size)
-    b2.size = tmpSize or freeBlock or prevUsed
-    nextB.prevHdr = b2
-    mappingInsert(tmpSize, fl, sl)
-    insertBlock(b2, t, fl, sl)
-
-    b.size = size or (b.size and prevState)
-  else:
-    nextB.size = nextB.size and not prevFree
-    b.size = b.size and not freeBlock # Now it's used
-
-  addSize(t, b)
-  return getBuffer(b)
-
-
-proc freeEx(p: pointer, t: var TLSF) =
-  var
-    fl = 0
-    sl = 0
-    b, tmpB: Pbhdr
-
-  assert(p != nil)
-  b = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead)
-  b.size = b.size or freeBlock
-
-  removeSize(t, b)
-  b.freePtr.prev = nil
-  b.freePtr.next = nil
-  tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
-  if (tmpB.size and freeBlock) != 0:
-    mappingInsert(tmpB.size and blockSize, fl, sl)
-    extractBlock(tmpB, t, fl, sl)
-    inc(b.size, (tmpB.size and blockSize) + bhdrOverhead)
-  if (b.size and prevFree) != 0:
-    tmpB = b.prevHdr
-    mappingInsert(tmpB.size and blockSize, fl, sl)
-    extractBlock(tmpB, t, fl, sl)
-    inc(tmpB.size, (b.size and blockSize) + bhdrOverhead)
-    b = tmpB
-  mappingInsert(b.size and blockSize, fl, sl)
-  insertBlock(b, t, fl, sl)
-
-  tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
-  tmpB.size = tmpB.size or prevFree
-  tmpB.prevHdr = b
-
-proc reallocEx(p: pointer, newSize: int, t: var TLSF): pointer = 
-  var
-    cpsize, fl, sl, tmpSize: int
-    b, tmpB, nextB: Pbhdr
-
-  assert(p != nil)
-  assert(newSize > 0)
-
-  b = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead)
-  nextB = getNextBlock(getBuffer(b), b.size and blockSize)
-  newSize = if newSize < minBlockSize: minBlockSize else: roundupSize(newSize)
-  tmpSize = b.size and blockSize
-  if newSize <= tmpSize:
-    removeSize(t, b)
-    if (nextB.size and freeBlock) != 0: 
-      mappingInsert(nextB.size and blockSize, fl, sl)
-      extractBlock(nextB, t, fl, sl)
-      inc(tmpSize, (nextB.size and blockSize) + bhdrOverhead)
-      nextB = getNextBlock(getBuffer(nextB), nextB.size and blockSize)
-      # We always reenter this free block because tmpSize will
-      # be greater then sizeof(Tbhdr)
-    dec(tmpSize, newSize)
-    if tmpSize >= sizeof(Tbhdr):
-      dec(tmpSize, bhdrOverhead)
-      tmpB = getNextBlock(getBuffer(b), newSize)
-      tmpB.size = tmpSize or freeBlock or prevUsed
-      nextB.prevHdr = tmpB
-      nextB.size = nextB.size or prevFree
-      mappingInsert(tmpSize, fl, sl)
-      insertBlock(tmpB, t, fl, sl)
-      b.size = newSize or (b.size and prevState)
-    addSize(t, b)
-    return getBuffer(b)
-  
-  if (nextB.size and freeBlock) != 0:
-    if newSize <= tmpSize + (nextB.size and blockSize):
-      removeSize(t, b)
-      mappingInsert(nextB.size and blockSize, fl, sl)
-      extractBlock(nextB, t, fl, sl)
-      inc(b.size, (nextB.size and blockSize) + bhdrOverhead)
-      nextB = getNextBlock(getBuffer(b), b.size and blockSize)
-      nextB.prevHdr = b
-      nextB.size = nextB.size and not prevFree
-      tmpSize = (b.size and blockSize) - newSize
-      if tmpSize >= sizeof(Tbhdr):
-        dec(tmpSize, bhdrOverhead)
-        tmpB = getNextBlock(getBuffer(b), newSize)
-        tmpB.size = tmpSize or freeBlock or prevUsed
-        nextB.prevHdr = tmpB
-        nextB.size = nextB.size or prevFree
-        mappingInsert(tmpSize, fl, sl)
-        insertBlock(tmpB, t, fl, sl)
-        b.size = newSize or (b.size and prevState)
-      addSize(t, b)
-      return getBuffer(b)
-
-  var ptrAux = mallocEx(newSize, t)
-  cpsize = if (b.size and blockSize) > newSize: newSize else:
-                                                (b.size and blockSize)
-  copyMem(ptrAux, p, cpsize)
-  freeEx(p, memPool)
-  return ptrAux
-
-
-proc ansiCrealloc(p: pointer, newSize: int, t: var TLSF): pointer = 
-  if p == nil: 
-    if newSize > 0: 
-      result = mallocEx(newSize, t)
-    else:
-      result = nil
-  elif newSize <= 0:
-    freeEx(p, t)
-    result = nil
-  else:
-    result = reallocEx(p, newSize, t)
-
-proc InitTLSF(t: var TLSF) = 
-  var areaSize = sizeof(TLSF) + BHDR_OVERHEAD * 8 # Just a safety constant
-  areaSize = max(areaSize, DEFAULT_areaSize)
-  var area = getNewArea(areaSize)
-  
-  
-  initMemoryPool(areaSize, area)
-
-  var
-    t: PLSF
-    b, ib: Pbhdr
-
-  t = cast[PLSF](memPool)
-  
-  zeroMem(area, areaSize)
-
-  t.signature = tlsfSignature
-  var ib = processArea(getNextBlock(memPool, roundupSize(sizeof(TLSF))), 
-                   rounddownSize(memPoolSize - sizeof(TLSF)))
-  var b = getNextBlock(getBuffer(ib), ib.size and blockSize)
-  freeEx(getBuffer(b), t)
-  t.areaHead = cast[PAreaInfo](getBuffer(ib))
-
-  t.used_size = memPoolSize - (b.size and blockSize)
-  t.max_size = t.used_size
-
-  # XXX
diff --git a/lib/winlean.nim b/lib/windows/winlean.nim
index 747ce7db5..b497ddad3 100644
--- a/lib/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -105,4 +105,82 @@ proc SetStdHandle*(nStdHandle: int32, hHandle: THANDLE): WINBOOL {.stdcall,
     dynlib: "kernel32", importc: "SetStdHandle".}

 proc FlushFileBuffers*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",

     importc: "FlushFileBuffers".}

-

+
+proc GetLastError*(): int32 {.importc, stdcall, dynlib: "kernel32".}
+proc FormatMessageA*(dwFlags: int32, lpSource: pointer,
+                    dwMessageId, dwLanguageId: int32,
+                    lpBuffer: pointer, nSize: int32,
+                    Arguments: pointer): int32 {.
+                    importc, stdcall, dynlib: "kernel32".}
+proc LocalFree*(p: pointer) {.importc, stdcall, dynlib: "kernel32".}
+
+proc GetCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {.
+  importc, dynlib: "kernel32", stdcall.}
+proc SetCurrentDirectoryA*(lpPathName: cstring): int32 {.
+  importc, dynlib: "kernel32", stdcall.}
+proc CreateDirectoryA*(pathName: cstring, security: Pointer): int32 {.
+  importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.}
+proc RemoveDirectoryA*(lpPathName: cstring): int32 {.
+  importc, dynlib: "kernel32", stdcall.}
+proc SetEnvironmentVariableA*(lpName, lpValue: cstring): int32 {.
+  stdcall, dynlib: "kernel32", importc.}
+
+proc GetModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {.
+  importc, dynlib: "kernel32", stdcall.}
+
+const
+  FILE_ATTRIBUTE_ARCHIVE* = 32'i32
+  FILE_ATTRIBUTE_COMPRESSED* = 2048'i32
+  FILE_ATTRIBUTE_NORMAL* = 128'i32
+  FILE_ATTRIBUTE_DIRECTORY* = 16'i32
+  FILE_ATTRIBUTE_HIDDEN* = 2'i32
+  FILE_ATTRIBUTE_READONLY* = 1'i32
+  FILE_ATTRIBUTE_SYSTEM* = 4'i32
+
+  MAX_PATH* = 260
+type
+  FILETIME* {.final, pure.} = object ## CANNOT BE int64 BECAUSE OF ALIGNMENT
+    dwLowDateTime*: int32
+    dwHighDateTime*: int32
+  TWIN32_FIND_DATA* {.pure.} = object
+    dwFileAttributes*: int32
+    ftCreationTime*: FILETIME
+    ftLastAccessTime*: FILETIME
+    ftLastWriteTime*: FILETIME
+    nFileSizeHigh*: int32
+    nFileSizeLow*: int32
+    dwReserved0: int32
+    dwReserved1: int32
+    cFileName*: array[0..(MAX_PATH) - 1, char]
+    cAlternateFileName*: array[0..13, char]
+proc FindFirstFileA*(lpFileName: cstring,
+                    lpFindFileData: var TWIN32_FIND_DATA): THANDLE {.
+    stdcall, dynlib: "kernel32", importc: "FindFirstFileA".}
+proc FindNextFileA*(hFindFile: THANDLE,
+                   lpFindFileData: var TWIN32_FIND_DATA): int32 {.
+    stdcall, dynlib: "kernel32", importc: "FindNextFileA".}
+proc FindClose*(hFindFile: THANDLE) {.stdcall, dynlib: "kernel32",
+  importc: "FindClose".}
+
+proc GetFullPathNameA*(lpFileName: cstring, nBufferLength: int32,
+                      lpBuffer: cstring, lpFilePart: var cstring): int32 {.
+                      stdcall, dynlib: "kernel32", importc.}
+proc GetFileAttributesA*(lpFileName: cstring): int32 {.
+                        stdcall, dynlib: "kernel32", importc.}
+proc SetFileAttributesA*(lpFileName: cstring, dwFileAttributes: int32): WINBOOL {.
+    stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".}
+
+proc CopyFileA*(lpExistingFileName, lpNewFileName: CString,
+               bFailIfExists: cint): cint {.
+  importc, stdcall, dynlib: "kernel32".}
+
+proc GetEnvironmentStringsA*(): cstring {.
+  stdcall, dynlib: "kernel32", importc.}
+proc FreeEnvironmentStringsA*(para1: cstring): int32 {.
+  stdcall, dynlib: "kernel32", importc.}
+
+proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".}
+
+proc rdFileTime*(f: FILETIME): int64 = 
+  result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
+
diff --git a/lib/base/cairo/cairo.nim b/lib/wrappers/cairo/cairo.nim
index 6da8183f3..6da8183f3 100644
--- a/lib/base/cairo/cairo.nim
+++ b/lib/wrappers/cairo/cairo.nim
diff --git a/lib/base/cairo/cairoft.nim b/lib/wrappers/cairo/cairoft.nim
index 2418aa922..2418aa922 100644
--- a/lib/base/cairo/cairoft.nim
+++ b/lib/wrappers/cairo/cairoft.nim
diff --git a/lib/base/cairo/cairowin32.nim b/lib/wrappers/cairo/cairowin32.nim
index 5d07c2611..5d07c2611 100644
--- a/lib/base/cairo/cairowin32.nim
+++ b/lib/wrappers/cairo/cairowin32.nim
diff --git a/lib/base/cairo/cairoxlib.nim b/lib/wrappers/cairo/cairoxlib.nim
index dfe44eb87..dfe44eb87 100644
--- a/lib/base/cairo/cairoxlib.nim
+++ b/lib/wrappers/cairo/cairoxlib.nim
diff --git a/lib/base/gtk/atk.nim b/lib/wrappers/gtk/atk.nim
index ae7a34c4b..ae7a34c4b 100644
--- a/lib/base/gtk/atk.nim
+++ b/lib/wrappers/gtk/atk.nim
diff --git a/lib/base/gtk/gdk2.nim b/lib/wrappers/gtk/gdk2.nim
index 0ca5056b5..0ca5056b5 100644
--- a/lib/base/gtk/gdk2.nim
+++ b/lib/wrappers/gtk/gdk2.nim
diff --git a/lib/base/gtk/gdk2pixbuf.nim b/lib/wrappers/gtk/gdk2pixbuf.nim
index daaa1479b..daaa1479b 100644
--- a/lib/base/gtk/gdk2pixbuf.nim
+++ b/lib/wrappers/gtk/gdk2pixbuf.nim
diff --git a/lib/base/gtk/gdkglext.nim b/lib/wrappers/gtk/gdkglext.nim
index 524b5f730..524b5f730 100644
--- a/lib/base/gtk/gdkglext.nim
+++ b/lib/wrappers/gtk/gdkglext.nim
diff --git a/lib/base/gtk/glib2.nim b/lib/wrappers/gtk/glib2.nim
index aca1b5551..aca1b5551 100644
--- a/lib/base/gtk/glib2.nim
+++ b/lib/wrappers/gtk/glib2.nim
diff --git a/lib/base/gtk/gtk2.nim b/lib/wrappers/gtk/gtk2.nim
index d1e72e708..d1e72e708 100644
--- a/lib/base/gtk/gtk2.nim
+++ b/lib/wrappers/gtk/gtk2.nim
diff --git a/lib/base/gtk/gtkglext.nim b/lib/wrappers/gtk/gtkglext.nim
index 38da5d25e..38da5d25e 100644
--- a/lib/base/gtk/gtkglext.nim
+++ b/lib/wrappers/gtk/gtkglext.nim
diff --git a/lib/base/gtk/gtkhtml.nim b/lib/wrappers/gtk/gtkhtml.nim
index d015a78bc..d015a78bc 100644
--- a/lib/base/gtk/gtkhtml.nim
+++ b/lib/wrappers/gtk/gtkhtml.nim
diff --git a/lib/base/gtk/libglade2.nim b/lib/wrappers/gtk/libglade2.nim
index 5e323680e..5e323680e 100644
--- a/lib/base/gtk/libglade2.nim
+++ b/lib/wrappers/gtk/libglade2.nim
diff --git a/lib/base/gtk/pango.nim b/lib/wrappers/gtk/pango.nim
index ade2da989..ade2da989 100644
--- a/lib/base/gtk/pango.nim
+++ b/lib/wrappers/gtk/pango.nim
diff --git a/lib/base/gtk/pangoutils.nim b/lib/wrappers/gtk/pangoutils.nim
index e6f3ab94c..e6f3ab94c 100644
--- a/lib/base/gtk/pangoutils.nim
+++ b/lib/wrappers/gtk/pangoutils.nim
diff --git a/lib/base/libcurl.nim b/lib/wrappers/libcurl.nim
index 5d54a2640..5d54a2640 100644
--- a/lib/base/libcurl.nim
+++ b/lib/wrappers/libcurl.nim
diff --git a/lib/base/lua/lauxlib.nim b/lib/wrappers/lua/lauxlib.nim
index 143a6cc46..b9a0a8d04 100644
--- a/lib/base/lua/lauxlib.nim
+++ b/lib/wrappers/lua/lauxlib.nim
@@ -21,7 +21,7 @@
 #**   In french or in english
 #
 
-import "lib/base/lua/lua"
+import lua
 
 proc lua_pushstring*(L: Plua_State, s: string)
   # compatibilty macros
diff --git a/lib/base/lua/lua.nim b/lib/wrappers/lua/lua.nim
index ab872fd23..9bf4e673e 100644
--- a/lib/base/lua/lua.nim
+++ b/lib/wrappers/lua/lua.nim
@@ -37,16 +37,16 @@
 
 when defined(MACOSX): 
   const 
-    LUA_NAME* = "liblua5.1.dylib"
-    LUA_LIB_NAME* = "liblua5.1.dylib"
+    LUA_NAME* = "liblua(5.2|5.1|5.0).dylib"
+    LUA_LIB_NAME* = "liblua(5.2|5.1|5.0).dylib"
 elif defined(UNIX): 
   const 
-    LUA_NAME* = "liblua5.1.so"
-    LUA_LIB_NAME* = "liblua5.1.so"
+    LUA_NAME* = "liblua(5.2|5.1|5.0).so.0"
+    LUA_LIB_NAME* = "liblua(5.2|5.1|5.0).so.0"
 else: 
   const 
-    LUA_NAME* = "lua5.1.dll"
-    LUA_LIB_NAME* = "lua5.1.dll"
+    LUA_NAME* = "lua(5.2|5.1|5.0).dll"
+    LUA_LIB_NAME* = "lua(5.2|5.1|5.0).dll"
 type 
   size_t* = int
   Psize_t* = ptr size_t
diff --git a/lib/base/lua/lualib.nim b/lib/wrappers/lua/lualib.nim
index efd3ab923..df5d53101 100644
--- a/lib/base/lua/lualib.nim
+++ b/lib/wrappers/lua/lualib.nim
@@ -19,7 +19,7 @@
 #**   In french or in english
 #
 
-import "lib/base/lua/lua"
+import lua
 
 const 
   LUA_COLIBNAME* = "coroutine"
diff --git a/lib/base/mysql.nim b/lib/wrappers/mysql.nim
index 60c6bd80c..60c6bd80c 100644
--- a/lib/base/mysql.nim
+++ b/lib/wrappers/mysql.nim
diff --git a/lib/base/odbcsql.nim b/lib/wrappers/odbcsql.nim
index 8f8804092..8f8804092 100644
--- a/lib/base/odbcsql.nim
+++ b/lib/wrappers/odbcsql.nim
diff --git a/lib/base/opengl/gl.nim b/lib/wrappers/opengl/gl.nim
index 79f09b544..79f09b544 100644
--- a/lib/base/opengl/gl.nim
+++ b/lib/wrappers/opengl/gl.nim
diff --git a/lib/base/opengl/gl.pp b/lib/wrappers/opengl/gl.pp
index f6e0ddc39..f6e0ddc39 100644
--- a/lib/base/opengl/gl.pp
+++ b/lib/wrappers/opengl/gl.pp
diff --git a/lib/base/opengl/glext.nim b/lib/wrappers/opengl/glext.nim
index 0a2138584..0a2138584 100644
--- a/lib/base/opengl/glext.nim
+++ b/lib/wrappers/opengl/glext.nim
diff --git a/lib/base/opengl/glext.pp b/lib/wrappers/opengl/glext.pp
index 4c9fc2119..4c9fc2119 100644
--- a/lib/base/opengl/glext.pp
+++ b/lib/wrappers/opengl/glext.pp
diff --git a/lib/base/opengl/glu.nim b/lib/wrappers/opengl/glu.nim
index 297f4d354..297f4d354 100644
--- a/lib/base/opengl/glu.nim
+++ b/lib/wrappers/opengl/glu.nim
diff --git a/lib/base/opengl/glu.pp b/lib/wrappers/opengl/glu.pp
index 1594085ed..1594085ed 100644
--- a/lib/base/opengl/glu.pp
+++ b/lib/wrappers/opengl/glu.pp
diff --git a/lib/base/opengl/glut.nim b/lib/wrappers/opengl/glut.nim
index 55ee18bda..55ee18bda 100644
--- a/lib/base/opengl/glut.nim
+++ b/lib/wrappers/opengl/glut.nim
diff --git a/lib/base/opengl/glut.pp b/lib/wrappers/opengl/glut.pp
index 3a6e7d9fc..3a6e7d9fc 100644
--- a/lib/base/opengl/glut.pp
+++ b/lib/wrappers/opengl/glut.pp
diff --git a/lib/base/opengl/glx.nim b/lib/wrappers/opengl/glx.nim
index a967acfc6..a967acfc6 100644
--- a/lib/base/opengl/glx.nim
+++ b/lib/wrappers/opengl/glx.nim
diff --git a/lib/base/opengl/glx.pp b/lib/wrappers/opengl/glx.pp
index 2b8c1eed7..2b8c1eed7 100644
--- a/lib/base/opengl/glx.pp
+++ b/lib/wrappers/opengl/glx.pp
diff --git a/lib/base/opengl/wingl.nim b/lib/wrappers/opengl/wingl.nim
index 2cebf8622..2cebf8622 100644
--- a/lib/base/opengl/wingl.nim
+++ b/lib/wrappers/opengl/wingl.nim
diff --git a/lib/base/opengl/wingl.pp b/lib/wrappers/opengl/wingl.pp
index 70be6674e..70be6674e 100644
--- a/lib/base/opengl/wingl.pp
+++ b/lib/wrappers/opengl/wingl.pp
diff --git a/lib/base/pcre.nim b/lib/wrappers/pcre/pcre.nim
index 4f4c27a09..05f937579 100644
--- a/lib/base/pcre.nim
+++ b/lib/wrappers/pcre/pcre.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2006 Andreas Rumpf
+#        (c) Copyright 2009 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
diff --git a/lib/base/pcre_all.c b/lib/wrappers/pcre/pcre_all.c
index bcda06e50..bcda06e50 100644
--- a/lib/base/pcre_all.c
+++ b/lib/wrappers/pcre/pcre_all.c
diff --git a/lib/base/postgres.nim b/lib/wrappers/postgres.nim
index c61edaa1e..d3c5e265b 100644
--- a/lib/base/postgres.nim
+++ b/lib/wrappers/postgres.nim
@@ -2,8 +2,8 @@
 # functions used by frontend postgres applications. It is based on
 # Postgresql's libpq-fe.h.
 #
-#  It is for postgreSQL version 7.4 and higher with support for the v3.0
-#  connection-protocol
+# It is for postgreSQL version 7.4 and higher with support for the v3.0
+# connection-protocol.
 #
 
 when defined(windows):
diff --git a/lib/wrappers/python.nim b/lib/wrappers/python.nim
new file mode 100644
index 000000000..c9f68e52d
--- /dev/null
+++ b/lib/wrappers/python.nim
@@ -0,0 +1,1581 @@
+#
+#    Light-weight binding for the Python interpreter
+#       (c) 2009 Andreas Rumpf 
+#    Based on 'PythonEngine' module by Dr. Dietmar Budelsky
+#
+#
+#************************************************************************
+#                                                                        
+# Module:  Unit 'PythonEngine'     Copyright (c) 1997                    
+#                                                                        
+# Version: 3.0                     Dr. Dietmar Budelsky                  
+# Sub-Version: 0.25                dbudelsky@web.de                      
+#                                  Germany                               
+#                                                                        
+#                                  Morgan Martinet                       
+#                                  4721 rue Brebeuf                      
+#                                  H2J 3L2 MONTREAL (QC)                 
+#                                  CANADA                                
+#                                  e-mail: mmm@free.fr                   
+#                                                                        
+#  look our page at: http://www.multimania.com/marat                     
+#************************************************************************
+#  Functionality:  Delphi Components that provide an interface to the    
+#                  Python language (see python.txt for more infos on     
+#                  Python itself).                                       
+#                                                                        
+#************************************************************************
+#  Contributors:                                                         
+#      Grzegorz Makarewicz (mak@mikroplan.com.pl)                        
+#      Andrew Robinson (andy@hps1.demon.co.uk)                           
+#      Mark Watts(mark_watts@hotmail.com)                                
+#      Olivier Deckmyn (olivier.deckmyn@mail.dotcom.fr)                  
+#      Sigve Tjora (public@tjora.no)                                     
+#      Mark Derricutt (mark@talios.com)                                  
+#      Igor E. Poteryaev (jah@mail.ru)                                   
+#      Yuri Filimonov (fil65@mail.ru)                                    
+#      Stefan Hoffmeister (Stefan.Hoffmeister@Econos.de)                 
+#************************************************************************
+# This source code is distributed with no WARRANTY, for no reason or use.
+# Everyone is allowed to use and change this code free for his own tasks 
+# and projects, as long as this header and its copyright text is intact. 
+# For changed versions of this code, which are public distributed the    
+# following additional conditions have to be fullfilled:                 
+# 1) The header has to contain a comment on the change and the author of 
+#    it.                                                                 
+# 2) A copy of the changed source has to be sent to the above E-Mail     
+#    address or my then valid address, if this is possible to the        
+#    author.                                                             
+# The second condition has the target to maintain an up to date central  
+# version of the component. If this condition is not acceptable for      
+# confidential or legal reasons, everyone is free to derive a component  
+# or to generate a diff file to my or other original sources.            
+# Dr. Dietmar Budelsky, 1997-11-17                                       
+#************************************************************************
+
+import 
+  dynlib
+
+
+when defined(windows): 
+  const dllname = "python(26|25|24|23|22|21|20|16|15).dll"
+elif defined(macosx):
+  const dllname = "libpython(2.6|2.5|2.4|2.3|2.2|2.1|2.0|1.6|1.5).dylib"
+else: 
+  const dllver = ".1"
+  const dllname = "libpython(2.6|2.5|2.4|2.3|2.2|2.1|2.0|1.6|1.5).so" & dllver
+  
+const 
+  PYT_METHOD_BUFFER_INCREASE* = 10
+  PYT_MEMBER_BUFFER_INCREASE* = 10
+  PYT_GETSET_BUFFER_INCREASE* = 10
+  METH_VARARGS* = 0x0001
+  METH_KEYWORDS* = 0x0002 # Masks for the co_flags field of PyCodeObject
+  CO_OPTIMIZED* = 0x0001
+  CO_NEWLOCALS* = 0x0002
+  CO_VARARGS* = 0x0004
+  CO_VARKEYWORDS* = 0x0008
+
+type                          # Rich comparison opcodes introduced in version 2.1
+  TRichComparisonOpcode* = enum 
+    pyLT, pyLE, pyEQ, pyNE, pyGT, pyGE
+
+const
+  Py_TPFLAGS_HAVE_GETCHARBUFFER* = (1 shl 0) # PySequenceMethods contains sq_contains
+  Py_TPFLAGS_HAVE_SEQUENCE_IN* = (1 shl 1) # Objects which participate in garbage collection (see objimp.h)
+  Py_TPFLAGS_GC* = (1 shl 2)  # PySequenceMethods and PyNumberMethods contain in-place operators
+  Py_TPFLAGS_HAVE_INPLACEOPS* = (1 shl 3) # PyNumberMethods do their own coercion */
+  Py_TPFLAGS_CHECKTYPES* = (1 shl 4)
+  Py_TPFLAGS_HAVE_RICHCOMPARE* = (1 shl 5) # Objects which are weakly referencable if their tp_weaklistoffset is >0
+                                           # XXX Should this have the same value as Py_TPFLAGS_HAVE_RICHCOMPARE?
+                                           # These both indicate a feature that appeared in the same alpha release.
+  Py_TPFLAGS_HAVE_WEAKREFS* = (1 shl 6) # tp_iter is defined
+  Py_TPFLAGS_HAVE_ITER* = (1 shl 7) # New members introduced by Python 2.2 exist
+  Py_TPFLAGS_HAVE_CLASS* = (1 shl 8) # Set if the type object is dynamically allocated
+  Py_TPFLAGS_HEAPTYPE* = (1 shl 9) # Set if the type allows subclassing
+  Py_TPFLAGS_BASETYPE* = (1 shl 10) # Set if the type is 'ready' -- fully initialized
+  Py_TPFLAGS_READY* = (1 shl 12) # Set while the type is being 'readied', to prevent recursive ready calls
+  Py_TPFLAGS_READYING* = (1 shl 13) # Objects support garbage collection (see objimp.h)
+  Py_TPFLAGS_HAVE_GC* = (1 shl 14)
+  Py_TPFLAGS_DEFAULT* = Py_TPFLAGS_HAVE_GETCHARBUFFER or
+      Py_TPFLAGS_HAVE_SEQUENCE_IN or Py_TPFLAGS_HAVE_INPLACEOPS or
+      Py_TPFLAGS_HAVE_RICHCOMPARE or Py_TPFLAGS_HAVE_WEAKREFS or
+      Py_TPFLAGS_HAVE_ITER or Py_TPFLAGS_HAVE_CLASS 
+
+type 
+  TPFlag* = enum 
+    tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfGC, tpfHaveInplaceOps, 
+    tpfCheckTypes, tpfHaveRichCompare, tpfHaveWeakRefs, tpfHaveIter, 
+    tpfHaveClass, tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC
+  TPFlags* = set[TPFlag]
+
+const 
+  TPFLAGS_DEFAULT* = {tpfHaveGetCharBuffer, tpfHaveSequenceIn, 
+    tpfHaveInplaceOps, tpfHaveRichCompare, tpfHaveWeakRefs, tpfHaveIter, 
+    tpfHaveClass}
+
+const # Python opcodes
+  single_input* = 256 
+  file_input* = 257
+  eval_input* = 258
+  funcdef* = 259
+  parameters* = 260
+  varargslist* = 261
+  fpdef* = 262
+  fplist* = 263
+  stmt* = 264
+  simple_stmt* = 265
+  small_stmt* = 266
+  expr_stmt* = 267
+  augassign* = 268
+  print_stmt* = 269
+  del_stmt* = 270
+  pass_stmt* = 271
+  flow_stmt* = 272
+  break_stmt* = 273
+  continue_stmt* = 274
+  return_stmt* = 275
+  raise_stmt* = 276
+  import_stmt* = 277
+  import_as_name* = 278
+  dotted_as_name* = 279
+  dotted_name* = 280
+  global_stmt* = 281
+  exec_stmt* = 282
+  assert_stmt* = 283
+  compound_stmt* = 284
+  if_stmt* = 285
+  while_stmt* = 286
+  for_stmt* = 287
+  try_stmt* = 288
+  except_clause* = 289
+  suite* = 290
+  test* = 291
+  and_test* = 291
+  not_test* = 293
+  comparison* = 294
+  comp_op* = 295
+  expr* = 296
+  xor_expr* = 297
+  and_expr* = 298
+  shift_expr* = 299
+  arith_expr* = 300
+  term* = 301
+  factor* = 302
+  power* = 303
+  atom* = 304
+  listmaker* = 305
+  lambdef* = 306
+  trailer* = 307
+  subscriptlist* = 308
+  subscript* = 309
+  sliceop* = 310
+  exprlist* = 311
+  testlist* = 312
+  dictmaker* = 313
+  classdef* = 314
+  arglist* = 315
+  argument* = 316
+  list_iter* = 317
+  list_for* = 318
+  list_if* = 319
+
+const 
+  T_SHORT* = 0
+  T_INT* = 1
+  T_LONG* = 2
+  T_FLOAT* = 3
+  T_DOUBLE* = 4
+  T_STRING* = 5
+  T_OBJECT* = 6
+  T_CHAR* = 7                 # 1-character string
+  T_BYTE* = 8                 # 8-bit signed int
+  T_UBYTE* = 9
+  T_USHORT* = 10
+  T_UINT* = 11
+  T_ULONG* = 12
+  T_STRING_INPLACE* = 13
+  T_OBJECT_EX* = 16 
+  READONLY* = 1
+  RO* = READONLY              # Shorthand 
+  READ_RESTRICTED* = 2
+  WRITE_RESTRICTED* = 4
+  RESTRICTED* = (READ_RESTRICTED or WRITE_RESTRICTED)
+
+type 
+  TPyMemberType* = enum 
+    mtShort, mtInt, mtLong, mtFloat, mtDouble, mtString, mtObject, mtChar, 
+    mtByte, mtUByte, mtUShort, mtUInt, mtULong, mtStringInplace, mtObjectEx
+  TPyMemberFlag* = enum 
+    mfDefault, mfReadOnly, mfReadRestricted, mfWriteRestricted, mfRestricted
+
+type 
+  PInt* = ptr int
+
+#  PLong* = ptr int32
+#  PFloat* = ptr float32
+#  PShort* = ptr int8
+  
+type 
+  PP_frozen* = ptr Pfrozen
+  P_frozen* = ptr Tfrozen
+  PPyObject* = ptr TPyObject
+  PPPyObject* = ptr PPyObject
+  PPPPyObject* = ptr PPPyObject
+  PPyIntObject* = ptr TPyIntObject
+  PPyTypeObject* = ptr TPyTypeObject
+  PPySliceObject* = ptr TPySliceObject
+  TPyCFunction* = proc (self, args: PPyObject): PPyObject{.cdecl.}
+  Tunaryfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Tbinaryfunc* = proc (ob1, ob2: PPyObject): PPyObject{.cdecl.}
+  Tternaryfunc* = proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.}
+  Tinquiry* = proc (ob1: PPyObject): int{.cdecl.}
+  Tcoercion* = proc (ob1, ob2: PPPyObject): int{.cdecl.}
+  Tintargfunc* = proc (ob1: PPyObject, i: int): PPyObject{.cdecl.}
+  Tintintargfunc* = proc (ob1: PPyObject, i1, i2: int): PPyObject{.cdecl.}
+  Tintobjargproc* = proc (ob1: PPyObject, i: int, ob2: PPyObject): int{.cdecl.}
+  Tintintobjargproc* = proc (ob1: PPyObject, i1, i2: int, ob2: PPyObject): int{.
+      cdecl.}
+  Tobjobjargproc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.}
+  Tpydestructor* = proc (ob: PPyObject){.cdecl.}
+  Tprintfunc* = proc (ob: PPyObject, f: TFile, i: int): int{.cdecl.}
+  Tgetattrfunc* = proc (ob1: PPyObject, name: cstring): PPyObject{.cdecl.}
+  Tsetattrfunc* = proc (ob1: PPyObject, name: cstring, ob2: PPyObject): int{.
+      cdecl.}
+  Tcmpfunc* = proc (ob1, ob2: PPyObject): int{.cdecl.}
+  Treprfunc* = proc (ob: PPyObject): PPyObject{.cdecl.}
+  Thashfunc* = proc (ob: PPyObject): int32{.cdecl.}
+  Tgetattrofunc* = proc (ob1, ob2: PPyObject): PPyObject{.cdecl.}
+  Tsetattrofunc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.} 
+  Tgetreadbufferproc* = proc (ob1: PPyObject, i: int, p: Pointer): int{.cdecl.}
+  Tgetwritebufferproc* = proc (ob1: PPyObject, i: int, p: Pointer): int{.cdecl.}
+  Tgetsegcountproc* = proc (ob1: PPyObject, i: int): int{.cdecl.}
+  Tgetcharbufferproc* = proc (ob1: PPyObject, i: int, pstr: cstring): int{.cdecl.}
+  Tobjobjproc* = proc (ob1, ob2: PPyObject): int{.cdecl.}
+  Tvisitproc* = proc (ob1: PPyObject, p: Pointer): int{.cdecl.}
+  Ttraverseproc* = proc (ob1: PPyObject, prc: TVisitproc, p: Pointer): int{.
+      cdecl.}
+  Trichcmpfunc* = proc (ob1, ob2: PPyObject, i: int): PPyObject{.cdecl.}
+  Tgetiterfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Titernextfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Tdescrgetfunc* = proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.}
+  Tdescrsetfunc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.}
+  Tinitproc* = proc (self, args, kwds: PPyObject): int{.cdecl.}
+  Tnewfunc* = proc (subtype: PPyTypeObject, args, kwds: PPyObject): PPyObject{.
+      cdecl.}
+  Tallocfunc* = proc (self: PPyTypeObject, nitems: int): PPyObject{.cdecl.}
+  TPyNumberMethods*{.final.} = object 
+    nb_add*: Tbinaryfunc
+    nb_substract*: Tbinaryfunc
+    nb_multiply*: Tbinaryfunc
+    nb_divide*: Tbinaryfunc
+    nb_remainder*: Tbinaryfunc
+    nb_divmod*: Tbinaryfunc
+    nb_power*: Tternaryfunc
+    nb_negative*: Tunaryfunc
+    nb_positive*: Tunaryfunc
+    nb_absolute*: Tunaryfunc
+    nb_nonzero*: Tinquiry
+    nb_invert*: Tunaryfunc
+    nb_lshift*: Tbinaryfunc
+    nb_rshift*: Tbinaryfunc
+    nb_and*: Tbinaryfunc
+    nb_xor*: Tbinaryfunc
+    nb_or*: Tbinaryfunc
+    nb_coerce*: Tcoercion
+    nb_int*: Tunaryfunc
+    nb_long*: Tunaryfunc
+    nb_float*: Tunaryfunc
+    nb_oct*: Tunaryfunc
+    nb_hex*: Tunaryfunc       #/ jah 29-sep-2000: updated for python 2.0
+                              #/                   added from .h
+    nb_inplace_add*: Tbinaryfunc
+    nb_inplace_subtract*: Tbinaryfunc
+    nb_inplace_multiply*: Tbinaryfunc
+    nb_inplace_divide*: Tbinaryfunc
+    nb_inplace_remainder*: Tbinaryfunc
+    nb_inplace_power*: Tternaryfunc
+    nb_inplace_lshift*: Tbinaryfunc
+    nb_inplace_rshift*: Tbinaryfunc
+    nb_inplace_and*: Tbinaryfunc
+    nb_inplace_xor*: Tbinaryfunc
+    nb_inplace_or*: Tbinaryfunc # Added in release 2.2
+                                # The following require the Py_TPFLAGS_HAVE_CLASS flag
+    nb_floor_divide*: Tbinaryfunc
+    nb_true_divide*: Tbinaryfunc
+    nb_inplace_floor_divide*: Tbinaryfunc
+    nb_inplace_true_divide*: Tbinaryfunc
+
+  PPyNumberMethods* = ptr TPyNumberMethods
+  TPySequenceMethods*{.final.} = object 
+    sq_length*: Tinquiry
+    sq_concat*: Tbinaryfunc
+    sq_repeat*: Tintargfunc
+    sq_item*: Tintargfunc
+    sq_slice*: Tintintargfunc
+    sq_ass_item*: Tintobjargproc
+    sq_ass_slice*: Tintintobjargproc 
+    sq_contains*: Tobjobjproc
+    sq_inplace_concat*: Tbinaryfunc
+    sq_inplace_repeat*: Tintargfunc
+
+  PPySequenceMethods* = ptr TPySequenceMethods
+  TPyMappingMethods*{.final.} = object 
+    mp_length*: Tinquiry
+    mp_subscript*: Tbinaryfunc
+    mp_ass_subscript*: Tobjobjargproc
+
+  PPyMappingMethods* = ptr TPyMappingMethods 
+  TPyBufferProcs*{.final.} = object 
+    bf_getreadbuffer*: Tgetreadbufferproc
+    bf_getwritebuffer*: Tgetwritebufferproc
+    bf_getsegcount*: Tgetsegcountproc
+    bf_getcharbuffer*: Tgetcharbufferproc
+
+  PPyBufferProcs* = ptr TPyBufferProcs
+  TPy_complex*{.final.} = object 
+    float*: float64
+    imag*: float64
+
+  TPyObject*{.pure.} = object 
+    ob_refcnt*: int
+    ob_type*: PPyTypeObject
+
+  TPyIntObject* = object of TPyObject
+    ob_ival*: int32
+
+  PByte* = ptr int8
+  Tfrozen*{.final.} = object 
+    name*: cstring
+    code*: PByte
+    size*: int
+
+  TPySliceObject* = object of TPyObject
+    start*, stop*, step*: PPyObject
+
+  PPyMethodDef* = ptr TPyMethodDef
+  TPyMethodDef*{.final.} = object  # structmember.h
+    ml_name*: cstring
+    ml_meth*: TPyCFunction
+    ml_flags*: int
+    ml_doc*: cstring
+
+  PPyMemberDef* = ptr TPyMemberDef
+  TPyMemberDef*{.final.} = object  # descrobject.h
+                                   # Descriptors
+    name*: cstring
+    theType*: int
+    offset*: int
+    flags*: int
+    doc*: cstring
+
+  Tgetter* = proc (obj: PPyObject, context: Pointer): PPyObject{.cdecl.}
+  Tsetter* = proc (obj, value: PPyObject, context: Pointer): int{.cdecl.}
+  PPyGetSetDef* = ptr TPyGetSetDef
+  TPyGetSetDef*{.final.} = object 
+    name*: cstring
+    get*: Tgetter
+    set_*: Tsetter
+    doc*: cstring
+    closure*: Pointer
+
+  Twrapperfunc* = proc (self, args: PPyObject, wrapped: Pointer): PPyObject{.
+      cdecl.}
+  pwrapperbase* = ptr Twrapperbase
+  Twrapperbase*{.final.} = object  # Various kinds of descriptor objects
+                                   ##define PyDescr_COMMON \
+                                   #          PyObject_HEAD \
+                                   #          PyTypeObject *d_type; \
+                                   #          PyObject *d_name
+                                   #  
+    name*: cstring
+    wrapper*: Twrapperfunc
+    doc*: cstring
+
+  PPyDescrObject* = ptr TPyDescrObject
+  TPyDescrObject* = object of TPyObject
+    d_type*: PPyTypeObject
+    d_name*: PPyObject
+
+  PPyMethodDescrObject* = ptr TPyMethodDescrObject
+  TPyMethodDescrObject* = object of TPyDescrObject
+    d_method*: PPyMethodDef
+
+  PPyMemberDescrObject* = ptr TPyMemberDescrObject
+  TPyMemberDescrObject* = object of TPyDescrObject
+    d_member*: PPyMemberDef
+
+  PPyGetSetDescrObject* = ptr TPyGetSetDescrObject
+  TPyGetSetDescrObject* = object of TPyDescrObject
+    d_getset*: PPyGetSetDef
+
+  PPyWrapperDescrObject* = ptr TPyWrapperDescrObject
+  TPyWrapperDescrObject* = object of TPyDescrObject # object.h
+    d_base*: pwrapperbase
+    d_wrapped*: Pointer       # This can be any function pointer
+  
+  TPyTypeObject* = object of TPyObject
+    ob_size*: int             # Number of items in variable part
+    tp_name*: cstring         # For printing
+    tp_basicsize*, tp_itemsize*: int # For allocation
+                                     # Methods to implement standard operations
+    tp_dealloc*: Tpydestructor
+    tp_print*: Tprintfunc
+    tp_getattr*: Tgetattrfunc
+    tp_setattr*: Tsetattrfunc
+    tp_compare*: Tcmpfunc
+    tp_repr*: Treprfunc       # Method suites for standard classes
+    tp_as_number*: PPyNumberMethods
+    tp_as_sequence*: PPySequenceMethods
+    tp_as_mapping*: PPyMappingMethods # More standard operations (here for binary compatibility)
+    tp_hash*: Thashfunc
+    tp_call*: Tternaryfunc
+    tp_str*: Treprfunc
+    tp_getattro*: Tgetattrofunc
+    tp_setattro*: Tsetattrofunc #/ jah 29-sep-2000: updated for python 2.0
+                                # Functions to access object as input/output buffer
+    tp_as_buffer*: PPyBufferProcs # Flags to define presence of optional/expanded features
+    tp_flags*: int32
+    tp_doc*: cstring          # Documentation string
+                              # call function for all accessible objects
+    tp_traverse*: Ttraverseproc # delete references to contained objects
+    tp_clear*: Tinquiry       # rich comparisons
+    tp_richcompare*: Trichcmpfunc # weak reference enabler
+    tp_weaklistoffset*: int32 # Iterators
+    tp_iter*: Tgetiterfunc
+    tp_iternext*: Titernextfunc # Attribute descriptor and subclassing stuff
+    tp_methods*: PPyMethodDef
+    tp_members*: PPyMemberDef
+    tp_getset*: PPyGetSetDef
+    tp_base*: PPyTypeObject
+    tp_dict*: PPyObject
+    tp_descr_get*: Tdescrgetfunc
+    tp_descr_set*: Tdescrsetfunc
+    tp_dictoffset*: int32
+    tp_init*: Tinitproc
+    tp_alloc*: Tallocfunc
+    tp_new*: Tnewfunc
+    tp_free*: Tpydestructor   # Low-level free-memory routine
+    tp_is_gc*: Tinquiry       # For PyObject_IS_GC
+    tp_bases*: PPyObject
+    tp_mro*: PPyObject        # method resolution order
+    tp_cache*: PPyObject
+    tp_subclasses*: PPyObject
+    tp_weaklist*: PPyObject   #More spares
+    tp_xxx7*: pointer
+    tp_xxx8*: pointer
+
+  PPyMethodChain* = ptr TPyMethodChain
+  TPyMethodChain*{.final.} = object 
+    methods*: PPyMethodDef
+    link*: PPyMethodChain
+
+  PPyClassObject* = ptr TPyClassObject
+  TPyClassObject* = object of TPyObject
+    cl_bases*: PPyObject      # A tuple of class objects
+    cl_dict*: PPyObject       # A dictionary
+    cl_name*: PPyObject       # A string
+                              # The following three are functions or NULL
+    cl_getattr*: PPyObject
+    cl_setattr*: PPyObject
+    cl_delattr*: PPyObject
+
+  PPyInstanceObject* = ptr TPyInstanceObject
+  TPyInstanceObject* = object of TPyObject 
+    in_class*: PPyClassObject # The class object
+    in_dict*: PPyObject       # A dictionary
+  
+  PPyMethodObject* = ptr TPyMethodObject
+  TPyMethodObject* = object of TPyObject # Bytecode object, compile.h
+    im_func*: PPyObject       # The function implementing the method
+    im_self*: PPyObject       # The instance it is bound to, or NULL
+    im_class*: PPyObject      # The class that defined the method
+  
+  PPyCodeObject* = ptr TPyCodeObject
+  TPyCodeObject* = object of TPyObject # from pystate.h
+    co_argcount*: int         # #arguments, except *args
+    co_nlocals*: int          # #local variables
+    co_stacksize*: int        # #entries needed for evaluation stack
+    co_flags*: int            # CO_..., see below
+    co_code*: PPyObject       # instruction opcodes (it hides a PyStringObject)
+    co_consts*: PPyObject     # list (constants used)
+    co_names*: PPyObject      # list of strings (names used)
+    co_varnames*: PPyObject   # tuple of strings (local variable names)
+    co_freevars*: PPyObject   # tuple of strings (free variable names)
+    co_cellvars*: PPyObject   # tuple of strings (cell variable names)
+                              # The rest doesn't count for hash/cmp
+    co_filename*: PPyObject   # string (where it was loaded from)
+    co_name*: PPyObject       # string (name, for reference)
+    co_firstlineno*: int      # first source line number
+    co_lnotab*: PPyObject     # string (encoding addr<->lineno mapping)
+  
+  PPyInterpreterState* = ptr TPyInterpreterState
+  PPyThreadState* = ptr TPyThreadState
+  PPyFrameObject* = ptr TPyFrameObject # Interpreter environments
+  TPyInterpreterState*{.final.} = object  # Thread specific information
+    next*: PPyInterpreterState
+    tstate_head*: PPyThreadState
+    modules*: PPyObject
+    sysdict*: PPyObject
+    builtins*: PPyObject
+    checkinterval*: int
+
+  TPyThreadState*{.final.} = object  # from frameobject.h
+    next*: PPyThreadState
+    interp*: PPyInterpreterState
+    frame*: PPyFrameObject
+    recursion_depth*: int
+    ticker*: int
+    tracing*: int
+    sys_profilefunc*: PPyObject
+    sys_tracefunc*: PPyObject
+    curexc_type*: PPyObject
+    curexc_value*: PPyObject
+    curexc_traceback*: PPyObject
+    exc_type*: PPyObject
+    exc_value*: PPyObject
+    exc_traceback*: PPyObject
+    dict*: PPyObject
+
+  PPyTryBlock* = ptr TPyTryBlock
+  TPyTryBlock*{.final.} = object 
+    b_type*: int              # what kind of block this is
+    b_handler*: int           # where to jump to find handler
+    b_level*: int             # value stack level to pop to
+  
+  CO_MAXBLOCKS* = range[0..19]
+  TPyFrameObject* = object of TPyObject # start of the VAR_HEAD of an object
+                                        # From traceback.c
+    ob_size*: int             # Number of items in variable part
+                              # End of the Head of an object
+    f_back*: PPyFrameObject   # previous frame, or NULL
+    f_code*: PPyCodeObject    # code segment
+    f_builtins*: PPyObject    # builtin symbol table (PyDictObject)
+    f_globals*: PPyObject     # global symbol table (PyDictObject)
+    f_locals*: PPyObject      # local symbol table (PyDictObject)
+    f_valuestack*: PPPyObject # points after the last local
+                              # Next free slot in f_valuestack. Frame creation sets to f_valuestack.
+                              # Frame evaluation usually NULLs it, but a frame that yields sets it
+                              # to the current stack top. 
+    f_stacktop*: PPPyObject
+    f_trace*: PPyObject       # Trace function
+    f_exc_type*, f_exc_value*, f_exc_traceback*: PPyObject
+    f_tstate*: PPyThreadState
+    f_lasti*: int             # Last instruction if called
+    f_lineno*: int            # Current line number
+    f_restricted*: int        # Flag set if restricted operations
+                              # in this scope
+    f_iblock*: int            # index in f_blockstack
+    f_blockstack*: array[CO_MAXBLOCKS, TPyTryBlock] # for try and loop blocks
+    f_nlocals*: int           # number of locals
+    f_ncells*: int
+    f_nfreevars*: int
+    f_stacksize*: int         # size of value stack
+    f_localsplus*: array[0..0, PPyObject] # locals+stack, dynamically sized
+  
+  PPyTraceBackObject* = ptr TPyTraceBackObject
+  TPyTraceBackObject* = object of TPyObject # Parse tree node interface
+    tb_next*: PPyTraceBackObject
+    tb_frame*: PPyFrameObject
+    tb_lasti*: int
+    tb_lineno*: int
+
+  PNode* = ptr Tnode
+  Tnode*{.final.} = object    # From weakrefobject.h
+    n_type*: int16
+    n_str*: cstring
+    n_lineno*: int16
+    n_nchildren*: int16
+    n_child*: PNode
+
+  PPyWeakReference* = ptr TPyWeakReference
+  TPyWeakReference* = object of TPyObject 
+    wr_object*: PPyObject
+    wr_callback*: PPyObject
+    hash*: int32
+    wr_prev*: PPyWeakReference
+    wr_next*: PPyWeakReference
+
+
+const                         
+  PyDateTime_DATE_DATASIZE* = 4 # # of bytes for year, month, and day
+  PyDateTime_TIME_DATASIZE* = 6 # # of bytes for hour, minute, second, and usecond
+  PyDateTime_DATETIME_DATASIZE* = 10 # # of bytes for year, month, 
+                                     # day, hour, minute, second, and usecond. 
+
+type 
+  TPyDateTime_Delta* = object of TPyObject
+    hashcode*: int            # -1 when unknown
+    days*: int                # -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS
+    seconds*: int             # 0 <= seconds < 24*3600 is invariant
+    microseconds*: int        # 0 <= microseconds < 1000000 is invariant
+  
+  PPyDateTime_Delta* = ptr TPyDateTime_Delta
+  TPyDateTime_TZInfo* = object of TPyObject # a pure abstract base clase
+  PPyDateTime_TZInfo* = ptr TPyDateTime_TZInfo 
+  TPyDateTime_BaseTZInfo* = object of TPyObject
+    hashcode*: int
+    hastzinfo*: bool          # boolean flag
+  
+  PPyDateTime_BaseTZInfo* = ptr TPyDateTime_BaseTZInfo 
+  TPyDateTime_BaseTime* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_TIME_DATASIZE), int8]
+
+  PPyDateTime_BaseTime* = ptr TPyDateTime_BaseTime
+  TPyDateTime_Time* = object of TPyDateTime_BaseTime # hastzinfo true
+    tzinfo*: PPyObject
+
+  PPyDateTime_Time* = ptr TPyDateTime_Time 
+  TPyDateTime_Date* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_DATE_DATASIZE), int8]
+
+  PPyDateTime_Date* = ptr TPyDateTime_Date 
+  TPyDateTime_BaseDateTime* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_DATETIME_DATASIZE), int8]
+
+  PPyDateTime_BaseDateTime* = ptr TPyDateTime_BaseDateTime
+  TPyDateTime_DateTime* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_DATETIME_DATASIZE), int8]
+    tzinfo*: PPyObject
+
+  PPyDateTime_DateTime* = ptr TPyDateTime_DateTime 
+
+#----------------------------------------------------#
+#                                                    #
+#         New exception classes                      #
+#                                                    #
+#----------------------------------------------------#
+
+#
+#  // Python's exceptions
+#  EPythonError   = object(Exception)
+#      EName: String;
+#      EValue: String;
+#  end;
+#  EPyExecError   = object(EPythonError)
+#  end;
+#
+#  // Standard exception classes of Python
+#
+#/// jah 29-sep-2000: updated for python 2.0
+#///                   base classes updated according python documentation
+#
+#{ Hierarchy of Python exceptions, Python 2.3, copied from <INSTALL>\Python\exceptions.c
+#
+#Exception\n\
+# |\n\
+# +-- SystemExit\n\
+# +-- StopIteration\n\
+# +-- StandardError\n\
+# |    |\n\
+# |    +-- KeyboardInterrupt\n\
+# |    +-- ImportError\n\
+# |    +-- EnvironmentError\n\
+# |    |    |\n\
+# |    |    +-- IOError\n\
+# |    |    +-- OSError\n\
+# |    |         |\n\
+# |    |         +-- WindowsError\n\
+# |    |         +-- VMSError\n\
+# |    |\n\
+# |    +-- EOFError\n\
+# |    +-- RuntimeError\n\
+# |    |    |\n\
+# |    |    +-- NotImplementedError\n\
+# |    |\n\
+# |    +-- NameError\n\
+# |    |    |\n\
+# |    |    +-- UnboundLocalError\n\
+# |    |\n\
+# |    +-- AttributeError\n\
+# |    +-- SyntaxError\n\
+# |    |    |\n\
+# |    |    +-- IndentationError\n\
+# |    |         |\n\
+# |    |         +-- TabError\n\
+# |    |\n\
+# |    +-- TypeError\n\
+# |    +-- AssertionError\n\
+# |    +-- LookupError\n\
+# |    |    |\n\
+# |    |    +-- IndexError\n\
+# |    |    +-- KeyError\n\
+# |    |\n\
+# |    +-- ArithmeticError\n\
+# |    |    |\n\
+# |    |    +-- OverflowError\n\
+# |    |    +-- ZeroDivisionError\n\
+# |    |    +-- FloatingPointError\n\
+# |    |\n\
+# |    +-- ValueError\n\
+# |    |    |\n\
+# |    |    +-- UnicodeError\n\
+# |    |        |\n\
+# |    |        +-- UnicodeEncodeError\n\
+# |    |        +-- UnicodeDecodeError\n\
+# |    |        +-- UnicodeTranslateError\n\
+# |    |\n\
+# |    +-- ReferenceError\n\
+# |    +-- SystemError\n\
+# |    +-- MemoryError\n\
+# |\n\
+# +---Warning\n\
+#      |\n\
+#      +-- UserWarning\n\
+#      +-- DeprecationWarning\n\
+#      +-- PendingDeprecationWarning\n\
+#      +-- SyntaxWarning\n\
+#      +-- OverflowWarning\n\
+#      +-- RuntimeWarning\n\
+#      +-- FutureWarning"
+#}
+#   EPyException = class (EPythonError);
+#   EPyStandardError = class (EPyException);
+#   EPyArithmeticError = class (EPyStandardError);
+#   EPyLookupError = class (EPyStandardError);
+#   EPyAssertionError = class (EPyStandardError);
+#   EPyAttributeError = class (EPyStandardError);
+#   EPyEOFError = class (EPyStandardError);
+#   EPyFloatingPointError = class (EPyArithmeticError);
+#   EPyEnvironmentError = class (EPyStandardError);
+#   EPyIOError = class (EPyEnvironmentError);
+#   EPyOSError = class (EPyEnvironmentError);
+#   EPyImportError = class (EPyStandardError);
+#   EPyIndexError = class (EPyLookupError);
+#   EPyKeyError = class (EPyLookupError);
+#   EPyKeyboardInterrupt = class (EPyStandardError);
+#   EPyMemoryError = class (EPyStandardError);
+#   EPyNameError = class (EPyStandardError);
+#   EPyOverflowError = class (EPyArithmeticError);
+#   EPyRuntimeError = class (EPyStandardError);
+#   EPyNotImplementedError = class (EPyRuntimeError);
+#   EPySyntaxError = class (EPyStandardError)
+#   public
+#      EFileName: string;
+#      ELineStr: string;
+#      ELineNumber: Integer;
+#      EOffset: Integer;
+#   end;
+#   EPyIndentationError = class (EPySyntaxError);
+#   EPyTabError = class (EPyIndentationError);
+#   EPySystemError = class (EPyStandardError);
+#   EPySystemExit = class (EPyException);
+#   EPyTypeError = class (EPyStandardError);
+#   EPyUnboundLocalError = class (EPyNameError);
+#   EPyValueError = class (EPyStandardError);
+#   EPyUnicodeError = class (EPyValueError);
+#   UnicodeEncodeError = class (EPyUnicodeError);
+#   UnicodeDecodeError = class (EPyUnicodeError);
+#   UnicodeTranslateError = class (EPyUnicodeError);
+#   EPyZeroDivisionError = class (EPyArithmeticError);
+#   EPyStopIteration = class(EPyException);
+#   EPyWarning = class (EPyException);
+#   EPyUserWarning = class (EPyWarning);
+#   EPyDeprecationWarning = class (EPyWarning);
+#   PendingDeprecationWarning = class (EPyWarning);
+#   FutureWarning = class (EPyWarning);
+#   EPySyntaxWarning = class (EPyWarning);
+#   EPyOverflowWarning = class (EPyWarning);
+#   EPyRuntimeWarning = class (EPyWarning);
+#   EPyReferenceError = class (EPyStandardError);
+#
+
+var 
+  PyArg_Parse*: proc (args: PPyObject, format: cstring): int{.cdecl, varargs.} 
+  PyArg_ParseTuple*: proc (args: PPyObject, format: cstring, x1: Pointer = nil, 
+                           x2: Pointer = nil, x3: Pointer = nil): int{.cdecl, varargs.} 
+  Py_BuildValue*: proc (format: cstring): PPyObject{.cdecl, varargs.} 
+  PyCode_Addr2Line*: proc (co: PPyCodeObject, addrq: int): int{.cdecl.}
+  DLL_Py_GetBuildInfo*: proc (): cstring{.cdecl.}
+
+var
+  Py_DebugFlag*: PInt
+  Py_VerboseFlag*: PInt
+  Py_InteractiveFlag*: PInt
+  Py_OptimizeFlag*: PInt
+  Py_NoSiteFlag*: PInt
+  Py_UseClassExceptionsFlag*: PInt
+  Py_FrozenFlag*: PInt
+  Py_TabcheckFlag*: PInt
+  Py_UnicodeFlag*: PInt
+  Py_IgnoreEnvironmentFlag*: PInt
+  Py_DivisionWarningFlag*: PInt 
+  #_PySys_TraceFunc:    PPPyObject;
+  #_PySys_ProfileFunc: PPPPyObject;
+  PyImport_FrozenModules*: PP_frozen
+  Py_None*: PPyObject
+  Py_Ellipsis*: PPyObject
+  Py_False*: PPyIntObject
+  Py_True*: PPyIntObject
+  Py_NotImplemented*: PPyObject
+  PyExc_AttributeError*: PPPyObject
+  PyExc_EOFError*: PPPyObject
+  PyExc_IOError*: PPPyObject
+  PyExc_ImportError*: PPPyObject
+  PyExc_IndexError*: PPPyObject
+  PyExc_KeyError*: PPPyObject
+  PyExc_KeyboardInterrupt*: PPPyObject
+  PyExc_MemoryError*: PPPyObject
+  PyExc_NameError*: PPPyObject
+  PyExc_OverflowError*: PPPyObject
+  PyExc_RuntimeError*: PPPyObject
+  PyExc_SyntaxError*: PPPyObject
+  PyExc_SystemError*: PPPyObject
+  PyExc_SystemExit*: PPPyObject
+  PyExc_TypeError*: PPPyObject
+  PyExc_ValueError*: PPPyObject
+  PyExc_ZeroDivisionError*: PPPyObject
+  PyExc_ArithmeticError*: PPPyObject
+  PyExc_Exception*: PPPyObject
+  PyExc_FloatingPointError*: PPPyObject
+  PyExc_LookupError*: PPPyObject
+  PyExc_StandardError*: PPPyObject
+  PyExc_AssertionError*: PPPyObject
+  PyExc_EnvironmentError*: PPPyObject
+  PyExc_IndentationError*: PPPyObject
+  PyExc_MemoryErrorInst*: PPPyObject
+  PyExc_NotImplementedError*: PPPyObject
+  PyExc_OSError*: PPPyObject
+  PyExc_TabError*: PPPyObject
+  PyExc_UnboundLocalError*: PPPyObject
+  PyExc_UnicodeError*: PPPyObject
+  PyExc_Warning*: PPPyObject
+  PyExc_DeprecationWarning*: PPPyObject
+  PyExc_RuntimeWarning*: PPPyObject
+  PyExc_SyntaxWarning*: PPPyObject
+  PyExc_UserWarning*: PPPyObject
+  PyExc_OverflowWarning*: PPPyObject
+  PyExc_ReferenceError*: PPPyObject
+  PyExc_StopIteration*: PPPyObject
+  PyExc_FutureWarning*: PPPyObject
+  PyExc_PendingDeprecationWarning*: PPPyObject
+  PyExc_UnicodeDecodeError*: PPPyObject
+  PyExc_UnicodeEncodeError*: PPPyObject
+  PyExc_UnicodeTranslateError*: PPPyObject
+  PyType_Type*: PPyTypeObject
+  PyCFunction_Type*: PPyTypeObject
+  PyCObject_Type*: PPyTypeObject
+  PyClass_Type*: PPyTypeObject
+  PyCode_Type*: PPyTypeObject
+  PyComplex_Type*: PPyTypeObject
+  PyDict_Type*: PPyTypeObject
+  PyFile_Type*: PPyTypeObject
+  PyFloat_Type*: PPyTypeObject
+  PyFrame_Type*: PPyTypeObject
+  PyFunction_Type*: PPyTypeObject
+  PyInstance_Type*: PPyTypeObject
+  PyInt_Type*: PPyTypeObject
+  PyList_Type*: PPyTypeObject
+  PyLong_Type*: PPyTypeObject
+  PyMethod_Type*: PPyTypeObject
+  PyModule_Type*: PPyTypeObject
+  PyObject_Type*: PPyTypeObject
+  PyRange_Type*: PPyTypeObject
+  PySlice_Type*: PPyTypeObject
+  PyString_Type*: PPyTypeObject
+  PyTuple_Type*: PPyTypeObject
+  PyBaseObject_Type*: PPyTypeObject
+  PyBuffer_Type*: PPyTypeObject
+  PyCallIter_Type*: PPyTypeObject
+  PyCell_Type*: PPyTypeObject
+  PyClassMethod_Type*: PPyTypeObject
+  PyProperty_Type*: PPyTypeObject
+  PySeqIter_Type*: PPyTypeObject
+  PyStaticMethod_Type*: PPyTypeObject
+  PySuper_Type*: PPyTypeObject
+  PySymtableEntry_Type*: PPyTypeObject
+  PyTraceBack_Type*: PPyTypeObject
+  PyUnicode_Type*: PPyTypeObject
+  PyWrapperDescr_Type*: PPyTypeObject
+  PyBaseString_Type*: PPyTypeObject
+  PyBool_Type*: PPyTypeObject
+  PyEnum_Type*: PPyTypeObject
+
+  #PyArg_GetObject: proc(args: PPyObject; nargs, i: integer; p_a: PPPyObject): integer; cdecl;
+  #PyArg_GetLong: proc(args: PPyObject; nargs, i: integer; p_a: PLong): integer; cdecl;
+  #PyArg_GetShort: proc(args: PPyObject; nargs, i: integer; p_a: PShort): integer; cdecl;
+  #PyArg_GetFloat: proc(args: PPyObject; nargs, i: integer; p_a: PFloat): integer; cdecl;
+  #PyArg_GetString: proc(args: PPyObject; nargs, i: integer; p_a: PString): integer; cdecl;
+  #PyArgs_VaParse:  proc (args: PPyObject; format: PChar; 
+  #                          va_list: array of const): integer; cdecl;
+  # Does not work!
+  # Py_VaBuildValue: proc (format: PChar; va_list: array of const): PPyObject; cdecl;
+  #PyBuiltin_Init: proc; cdecl;
+proc PyComplex_FromCComplex*(c: TPy_complex): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyComplex_FromDoubles*(realv, imag: float64): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyComplex_RealAsDouble*(op: PPyObject): float64{.cdecl, importc, dynlib: dllname.}
+proc PyComplex_ImagAsDouble*(op: PPyObject): float64{.cdecl, importc, dynlib: dllname.}
+proc PyComplex_AsCComplex*(op: PPyObject): TPy_complex{.cdecl, importc, dynlib: dllname.}
+proc PyCFunction_GetFunction*(ob: PPyObject): Pointer{.cdecl, importc, dynlib: dllname.}
+proc PyCFunction_GetSelf*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyCallable_Check*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyCObject_FromVoidPtr*(cobj, destruct: Pointer): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyCObject_AsVoidPtr*(ob: PPyObject): Pointer{.cdecl, importc, dynlib: dllname.}
+proc PyClass_New*(ob1, ob2, ob3: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyClass_IsSubclass*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc Py_InitModule4*(name: cstring, methods: PPyMethodDef, doc: cstring, 
+                         passthrough: PPyObject, Api_Version: int): PPyObject{.
+      cdecl, importc, dynlib: dllname.}
+proc PyErr_BadArgument*(): int{.cdecl, importc, dynlib: dllname.}
+proc PyErr_BadInternalCall*(){.cdecl, importc, dynlib: dllname.}
+proc PyErr_CheckSignals*(): int{.cdecl, importc, dynlib: dllname.}
+proc PyErr_Clear*(){.cdecl, importc, dynlib: dllname.}
+proc PyErr_Fetch*(errtype, errvalue, errtraceback: PPPyObject){.cdecl, importc, dynlib: dllname.}
+proc PyErr_NoMemory*(): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyErr_Occurred*(): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyErr_Print*(){.cdecl, importc, dynlib: dllname.}
+proc PyErr_Restore*(errtype, errvalue, errtraceback: PPyObject){.cdecl, importc, dynlib: dllname.}
+proc PyErr_SetFromErrno*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyErr_SetNone*(value: PPyObject){.cdecl, importc, dynlib: dllname.}
+proc PyErr_SetObject*(ob1, ob2: PPyObject){.cdecl, importc, dynlib: dllname.}
+proc PyErr_SetString*(ErrorObject: PPyObject, text: cstring){.cdecl, importc, dynlib: dllname.}
+proc PyImport_GetModuleDict*(): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyInt_FromLong*(x: int32): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc Py_Initialize*(){.cdecl, importc, dynlib: dllname.}
+proc Py_Exit*(RetVal: int){.cdecl, importc, dynlib: dllname.}
+proc PyEval_GetBuiltins*(): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_GetItem*(mp, key: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_SetItem*(mp, key, item: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyDict_DelItem*(mp, key: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyDict_Clear*(mp: PPyObject){.cdecl, importc, dynlib: dllname.}
+proc PyDict_Next*(mp: PPyObject, pos: PInt, key, value: PPPyObject): int{.
+      cdecl, importc, dynlib: dllname.}
+proc PyDict_Keys*(mp: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_Values*(mp: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_Items*(mp: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_Size*(mp: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyDict_DelItemString*(dp: PPyObject, key: cstring): int{.cdecl, importc, dynlib: dllname.}
+proc PyDict_New*(): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_GetItemString*(dp: PPyObject, key: cstring): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyDict_SetItemString*(dp: PPyObject, key: cstring, item: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}
+proc PyDictProxy_New*(obj: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyModule_GetDict*(module: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyObject_Str*(v: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyRun_String*(str: cstring, start: int, globals: PPyObject, 
+                       locals: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyRun_SimpleString*(str: cstring): int{.cdecl, importc, dynlib: dllname.}
+proc PyString_AsString*(ob: PPyObject): cstring{.cdecl, importc, dynlib: dllname.}
+proc PyString_FromString*(str: cstring): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PySys_SetArgv*(argc: int, argv: cstringArray){.cdecl, importc, dynlib: dllname.} 
+  #+ means, Grzegorz or me has tested his non object version of this function
+  #+
+proc PyCFunction_New*(md: PPyMethodDef, ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyEval_CallObject*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_CallObjectWithKeywords*(ob1, ob2, ob3: PPyObject): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyEval_GetFrame*(): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_GetGlobals*(): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_GetLocals*(): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_GetOwner*(): PPyObject {.cdecl, importc, dynlib: dllname.}
+proc PyEval_GetRestricted*(): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_InitThreads*(){.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_RestoreThread*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_SaveThread*(): PPyThreadState{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_FromString*(pc1, pc2: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_GetLine*(ob: PPyObject, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_Name*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_SetBufSize*(ob: PPyObject, i: int){.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_SoftSpace*(ob: PPyObject, i: int): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_WriteObject*(ob1, ob2: PPyObject, i: int): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyFile_WriteString*(s: cstring, ob: PPyObject){.cdecl, importc, dynlib: dllname.} #+
+proc PyFloat_AsDouble*(ob: PPyObject): float64{.cdecl, importc, dynlib: dllname.} #+
+proc PyFloat_FromDouble*(db: float64): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFunction_GetCode*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFunction_GetGlobals*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyFunction_New*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyImport_AddModule*(name: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyImport_Cleanup*(){.cdecl, importc, dynlib: dllname.} #-
+proc PyImport_GetMagicNumber*(): int32{.cdecl, importc, dynlib: dllname.} #+
+proc PyImport_ImportFrozenModule*(key: cstring): int{.cdecl, importc, dynlib: dllname.} #+
+proc PyImport_ImportModule*(name: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyImport_Import*(name: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+                                                               
+proc PyImport_Init*() {.cdecl, importc, dynlib: dllname.}
+proc PyImport_ReloadModule*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyInstance_New*(obClass, obArg, obKW: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyInt_AsLong*(ob: PPyObject): int32{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_Append*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_AsTuple*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyList_GetItem*(ob: PPyObject, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_GetSlice*(ob: PPyObject, i1, i2: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_Insert*(dp: PPyObject, idx: int, item: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_New*(size: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_Reverse*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_SetItem*(dp: PPyObject, idx: int, item: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_SetSlice*(ob: PPyObject, i1, i2: int, ob2: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}                 #+
+proc PyList_Size*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyList_Sort*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_AsDouble*(ob: PPyObject): float64{.cdecl, importc, dynlib: dllname.} #+
+proc PyLong_AsLong*(ob: PPyObject): int32{.cdecl, importc, dynlib: dllname.} #+
+proc PyLong_FromDouble*(db: float64): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyLong_FromLong*(L: int32): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_FromString*(pc: cstring, ppc: var cstring, i: int): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyLong_FromUnsignedLong*(val: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_AsUnsignedLong*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_FromUnicode*(ob: PPyObject, a, b: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_FromLongLong*(val: Int64): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyLong_AsLongLong*(ob: PPyObject): Int64{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_Check*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_GetItemString*(ob: PPyObject, key: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_HasKey*(ob, key: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_HasKeyString*(ob: PPyObject, key: cstring): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_Length*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyMapping_SetItemString*(ob: PPyObject, key: cstring, value: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyMethod_Class*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyMethod_Function*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyMethod_New*(ob1, ob2, ob3: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyMethod_Self*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyModule_GetName*(ob: PPyObject): cstring{.cdecl, importc, dynlib: dllname.} #-
+proc PyModule_New*(key: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Absolute*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Add*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_And*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Check*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Coerce*(ob1, ob2: var PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Divide*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_FloorDivide*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_TrueDivide*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Divmod*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Float*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Int*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Invert*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Long*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Lshift*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Multiply*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Negative*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Or*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Positive*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Power*(ob1, ob2, ob3: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Remainder*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Rshift*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Subtract*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyNumber_Xor*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyOS_InitInterrupts*(){.cdecl, importc, dynlib: dllname.} #-
+proc PyOS_InterruptOccurred*(): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_CallObject*(ob, args: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_Compare*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GetAttr*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyObject_GetAttrString*(ob: PPyObject, c: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GetItem*(ob, key: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_DelItem*(ob, key: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_HasAttrString*(ob: PPyObject, key: cstring): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_Hash*(ob: PPyObject): int32{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_IsTrue*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_Length*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_Repr*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_SetAttr*(ob1, ob2, ob3: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_SetAttrString*(ob: PPyObject, key: cstring, value: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyObject_SetItem*(ob1, ob2, ob3: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_Init*(ob: PPyObject, t: PPyTypeObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_InitVar*(ob: PPyObject, t: PPyTypeObject, size: int): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyObject_New*(t: PPyTypeObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_NewVar*(t: PPyTypeObject, size: int): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyObject_Free*(ob: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_IsInstance*(inst, cls: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_IsSubclass*(derived, cls: PPyObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyObject_GenericGetAttr*(obj, name: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyObject_GenericSetAttr*(obj, name, value: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_Malloc*(size: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_New*(t: PPyTypeObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_NewVar*(t: PPyTypeObject, size: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_Resize*(t: PPyObject, newsize: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_Del*(ob: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_Track*(ob: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyObject_GC_UnTrack*(ob: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyRange_New*(l1, l2, l3: int32, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Check*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Concat*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Count*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_GetItem*(ob: PPyObject, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_GetSlice*(ob: PPyObject, i1, i2: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_In*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Index*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Length*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Repeat*(ob: PPyObject, count: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_SetItem*(ob: PPyObject, i: int, value: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PySequence_SetSlice*(ob: PPyObject, i1, i2: int, value: PPyObject): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PySequence_DelSlice*(ob: PPyObject, i1, i2: int): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Tuple*(ob: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PySequence_Contains*(ob, value: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySlice_GetIndices*(ob: PPySliceObject, len: int, 
+                             start, stop, step: var int): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySlice_GetIndicesEx*(ob: PPySliceObject, len: int, 
+                               start, stop, step, slicelength: var int): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PySlice_New*(start, stop, step: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyString_Concat*(ob1: var PPyObject, ob2: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyString_ConcatAndDel*(ob1: var PPyObject, ob2: PPyObject){.cdecl, importc, dynlib: dllname.} #-
+proc PyString_Format*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyString_FromStringAndSize*(s: cstring, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyString_Size*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyString_DecodeEscape*(s: cstring, length: int, errors: cstring, 
+                                unicode: int, recode_encoding: cstring): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyString_Repr*(ob: PPyObject, smartquotes: int): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PySys_GetObject*(s: cstring): PPyObject{.cdecl, importc, dynlib: dllname.} 
+#-
+#PySys_Init:procedure; cdecl, importc, dynlib: dllname;
+#-
+proc PySys_SetObject*(s: cstring, ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PySys_SetPath*(path: cstring){.cdecl, importc, dynlib: dllname.} #-
+#PyTraceBack_Fetch:function:PPyObject; cdecl, importc, dynlib: dllname;
+#-
+proc PyTraceBack_Here*(p: pointer): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyTraceBack_Print*(ob1, ob2: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+#PyTraceBack_Store:function (ob:PPyObject):integer; cdecl, importc, dynlib: dllname;
+#+
+proc PyTuple_GetItem*(ob: PPyObject, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc PyTuple_GetSlice*(ob: PPyObject, i1, i2: int): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyTuple_New*(size: int): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyTuple_SetItem*(ob: PPyObject, key: int, value: PPyObject): int{.cdecl, importc, dynlib: dllname.} #+
+proc PyTuple_Size*(ob: PPyObject): int{.cdecl, importc, dynlib: dllname.} #+
+proc PyType_IsSubtype*(a, b: PPyTypeObject): int{.cdecl, importc, dynlib: dllname.}
+proc PyType_GenericAlloc*(atype: PPyTypeObject, nitems: int): PPyObject{.
+      cdecl, importc, dynlib: dllname.}
+proc PyType_GenericNew*(atype: PPyTypeObject, args, kwds: PPyObject): PPyObject{.
+      cdecl, importc, dynlib: dllname.}
+proc PyType_Ready*(atype: PPyTypeObject): int{.cdecl, importc, dynlib: dllname.} #+
+proc PyUnicode_FromWideChar*(w: pointer, size: int): PPyObject{.cdecl, importc, dynlib: dllname.} #+
+proc PyUnicode_AsWideChar*(unicode: PPyObject, w: pointer, size: int): int{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc PyUnicode_FromOrdinal*(ordinal: int): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyWeakref_GetObject*(theRef: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyWeakref_NewProxy*(ob, callback: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyWeakref_NewRef*(ob, callback: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyWrapper_New*(ob1, ob2: PPyObject): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc PyBool_FromLong*(ok: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc Py_AtExit*(prc: proc ()): int{.cdecl, importc, dynlib: dllname.} #-
+#Py_Cleanup:procedure; cdecl, importc, dynlib: dllname;
+#-
+proc Py_CompileString*(s1, s2: cstring, i: int): PPyObject{.cdecl, importc, dynlib: dllname.} #-
+proc Py_FatalError*(s: cstring){.cdecl, importc, dynlib: dllname.} #-
+proc Py_FindMethod*(md: PPyMethodDef, ob: PPyObject, key: cstring): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc Py_FindMethodInChain*(mc: PPyMethodChain, ob: PPyObject, key: cstring): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc Py_FlushLine*(){.cdecl, importc, dynlib: dllname.} #+
+proc Py_Finalize*(){.cdecl, importc, dynlib: dllname.} #-
+proc PyErr_ExceptionMatches*(exc: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyErr_GivenExceptionMatches*(raised_exc, exc: PPyObject): int{.cdecl, importc, dynlib: dllname.} #-
+proc PyEval_EvalCode*(co: PPyCodeObject, globals, locals: PPyObject): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #+
+proc Py_GetVersion*(): cstring{.cdecl, importc, dynlib: dllname.} #+
+proc Py_GetCopyright*(): cstring{.cdecl, importc, dynlib: dllname.} #+
+proc Py_GetExecPrefix*(): cstring{.cdecl, importc, dynlib: dllname.} #+
+proc Py_GetPath*(): cstring{.cdecl, importc, dynlib: dllname.} #+
+proc Py_GetPrefix*(): cstring{.cdecl, importc, dynlib: dllname.} #+
+proc Py_GetProgramName*(): cstring{.cdecl, importc, dynlib: dllname.} #-
+proc PyParser_SimpleParseString*(str: cstring, start: int): PNode{.cdecl, importc, dynlib: dllname.} #-
+proc PyNode_Free*(n: PNode){.cdecl, importc, dynlib: dllname.} #-
+proc PyErr_NewException*(name: cstring, base, dict: PPyObject): PPyObject{.
+      cdecl, importc, dynlib: dllname.}                 #-
+proc Py_Malloc*(size: int): Pointer {.cdecl, importc, dynlib: dllname.}
+proc PyMem_Malloc*(size: int): Pointer {.cdecl, importc, dynlib: dllname.}
+proc PyObject_CallMethod*(obj: PPyObject, theMethod, 
+                              format: cstring): PPyObject{.cdecl, importc, dynlib: dllname.}
+proc Py_SetProgramName*(name: cstring){.cdecl, importc, dynlib: dllname.}
+proc Py_IsInitialized*(): int{.cdecl, importc, dynlib: dllname.}
+proc Py_GetProgramFullPath*(): cstring{.cdecl, importc, dynlib: dllname.}
+proc Py_NewInterpreter*(): PPyThreadState{.cdecl, importc, dynlib: dllname.}
+proc Py_EndInterpreter*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.}
+proc PyEval_AcquireLock*(){.cdecl, importc, dynlib: dllname.}
+proc PyEval_ReleaseLock*(){.cdecl, importc, dynlib: dllname.}
+proc PyEval_AcquireThread*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.}
+proc PyEval_ReleaseThread*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.}
+proc PyInterpreterState_New*(): PPyInterpreterState{.cdecl, importc, dynlib: dllname.}
+proc PyInterpreterState_Clear*(interp: PPyInterpreterState){.cdecl, importc, dynlib: dllname.}
+proc PyInterpreterState_Delete*(interp: PPyInterpreterState){.cdecl, importc, dynlib: dllname.}
+proc PyThreadState_New*(interp: PPyInterpreterState): PPyThreadState{.cdecl, importc, dynlib: dllname.}
+proc PyThreadState_Clear*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.}
+proc PyThreadState_Delete*(tstate: PPyThreadState){.cdecl, importc, dynlib: dllname.}
+proc PyThreadState_Get*(): PPyThreadState{.cdecl, importc, dynlib: dllname.}
+proc PyThreadState_Swap*(tstate: PPyThreadState): PPyThreadState{.cdecl, importc, dynlib: dllname.} 
+
+#Further exported Objects, may be implemented later
+#
+#    PyCode_New: Pointer;
+#    PyErr_SetInterrupt: Pointer;
+#    PyFile_AsFile: Pointer;
+#    PyFile_FromFile: Pointer;
+#    PyFloat_AsString: Pointer;
+#    PyFrame_BlockPop: Pointer;
+#    PyFrame_BlockSetup: Pointer;
+#    PyFrame_ExtendStack: Pointer;
+#    PyFrame_FastToLocals: Pointer;
+#    PyFrame_LocalsToFast: Pointer;
+#    PyFrame_New: Pointer;
+#    PyGrammar_AddAccelerators: Pointer;
+#    PyGrammar_FindDFA: Pointer;
+#    PyGrammar_LabelRepr: Pointer;
+#    PyInstance_DoBinOp: Pointer;
+#    PyInt_GetMax: Pointer;
+#    PyMarshal_Init: Pointer;
+#    PyMarshal_ReadLongFromFile: Pointer;
+#    PyMarshal_ReadObjectFromFile: Pointer;
+#    PyMarshal_ReadObjectFromString: Pointer;
+#    PyMarshal_WriteLongToFile: Pointer;
+#    PyMarshal_WriteObjectToFile: Pointer;
+#    PyMember_Get: Pointer;
+#    PyMember_Set: Pointer;
+#    PyNode_AddChild: Pointer;
+#    PyNode_Compile: Pointer;
+#    PyNode_New: Pointer;
+#    PyOS_GetLastModificationTime: Pointer;
+#    PyOS_Readline: Pointer;
+#    PyOS_strtol: Pointer;
+#    PyOS_strtoul: Pointer;
+#    PyObject_CallFunction: Pointer;
+#    PyObject_CallMethod: Pointer;
+#    PyObject_Print: Pointer;
+#    PyParser_AddToken: Pointer;
+#    PyParser_Delete: Pointer;
+#    PyParser_New: Pointer;
+#    PyParser_ParseFile: Pointer;
+#    PyParser_ParseString: Pointer;
+#    PyParser_SimpleParseFile: Pointer;
+#    PyRun_AnyFile: Pointer;
+#    PyRun_File: Pointer;
+#    PyRun_InteractiveLoop: Pointer;
+#    PyRun_InteractiveOne: Pointer;
+#    PyRun_SimpleFile: Pointer;
+#    PySys_GetFile: Pointer;
+#    PyToken_OneChar: Pointer;
+#    PyToken_TwoChars: Pointer;
+#    PyTokenizer_Free: Pointer;
+#    PyTokenizer_FromFile: Pointer;
+#    PyTokenizer_FromString: Pointer;
+#    PyTokenizer_Get: Pointer;
+#    Py_Main: Pointer;
+#    _PyObject_NewVar: Pointer;
+#    _PyParser_Grammar: Pointer;
+#    _PyParser_TokenNames: Pointer;
+#    _PyThread_Started: Pointer;
+#    _Py_c_diff: Pointer;
+#    _Py_c_neg: Pointer;
+#    _Py_c_pow: Pointer;
+#    _Py_c_prod: Pointer;
+#    _Py_c_quot: Pointer;
+#    _Py_c_sum: Pointer;
+#
+
+# This function handles all cardinals, pointer types (with no adjustment of pointers!)
+# (Extended) floats, which are handled as Python doubles and currencies, handled
+# as (normalized) Python doubles.
+proc PyImport_ExecCodeModule*(name: String, codeobject: PPyObject): PPyObject
+proc PyString_Check*(obj: PPyObject): bool
+proc PyString_CheckExact*(obj: PPyObject): bool
+proc PyFloat_Check*(obj: PPyObject): bool
+proc PyFloat_CheckExact*(obj: PPyObject): bool
+proc PyInt_Check*(obj: PPyObject): bool
+proc PyInt_CheckExact*(obj: PPyObject): bool
+proc PyLong_Check*(obj: PPyObject): bool
+proc PyLong_CheckExact*(obj: PPyObject): bool
+proc PyTuple_Check*(obj: PPyObject): bool
+proc PyTuple_CheckExact*(obj: PPyObject): bool
+proc PyInstance_Check*(obj: PPyObject): bool
+proc PyClass_Check*(obj: PPyObject): bool
+proc PyMethod_Check*(obj: PPyObject): bool
+proc PyList_Check*(obj: PPyObject): bool
+proc PyList_CheckExact*(obj: PPyObject): bool
+proc PyDict_Check*(obj: PPyObject): bool
+proc PyDict_CheckExact*(obj: PPyObject): bool
+proc PyModule_Check*(obj: PPyObject): bool
+proc PyModule_CheckExact*(obj: PPyObject): bool
+proc PySlice_Check*(obj: PPyObject): bool
+proc PyFunction_Check*(obj: PPyObject): bool
+proc PyUnicode_Check*(obj: PPyObject): bool
+proc PyUnicode_CheckExact*(obj: PPyObject): bool
+proc PyType_IS_GC*(t: PPyTypeObject): bool
+proc PyObject_IS_GC*(obj: PPyObject): bool
+proc PyBool_Check*(obj: PPyObject): bool
+proc PyBaseString_Check*(obj: PPyObject): bool
+proc PyEnum_Check*(obj: PPyObject): bool
+proc PyObject_TypeCheck*(obj: PPyObject, t: PPyTypeObject): bool
+proc Py_InitModule*(name: cstring, md: PPyMethodDef): PPyObject
+proc PyType_HasFeature*(AType: PPyTypeObject, AFlag: int): bool
+# implementation
+
+proc Py_INCREF*(op: PPyObject) {.inline.} = 
+  Inc(op.ob_refcnt)
+
+proc Py_DECREF*(op: PPyObject) {.inline.} = 
+  Dec(op.ob_refcnt)
+  if op.ob_refcnt == 0: 
+    op.ob_type.tp_dealloc(op)
+
+proc Py_XINCREF*(op: PPyObject) {.inline.} = 
+  if op != nil: Py_INCREF(op)
+  
+proc Py_XDECREF*(op: PPyObject) {.inline.} = 
+  if op != nil: Py_DECREF(op)
+  
+proc PyImport_ExecCodeModule(name: string, codeobject: PPyObject): PPyObject = 
+  var m, d, v, modules: PPyObject
+  m = PyImport_AddModule(cstring(name))
+  if m == nil: 
+    return nil
+  d = PyModule_GetDict(m)
+  if PyDict_GetItemString(d, "__builtins__") == nil: 
+    if PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins()) != 0: 
+      return nil
+  if PyDict_SetItemString(d, "__file__", 
+                          PPyCodeObject(codeobject).co_filename) != 0: 
+    PyErr_Clear() # Not important enough to report
+  v = PyEval_EvalCode(PPyCodeObject(codeobject), d, d) # XXX owner ?
+  if v == nil: 
+    return nil
+  Py_XDECREF(v)
+  modules = PyImport_GetModuleDict()
+  if PyDict_GetItemString(modules, cstring(name)) == nil: 
+    PyErr_SetString(PyExc_ImportError^ , cstring(
+        "Loaded module " & name & "not found in sys.modules"))
+    return nil
+  Py_XINCREF(m)
+  Result = m
+
+proc PyString_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyString_Type)
+
+proc PyString_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyString_Type)
+
+proc PyFloat_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyFloat_Type)
+
+proc PyFloat_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyFloat_Type)
+
+proc PyInt_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyInt_Type)
+
+proc PyInt_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyInt_Type)
+
+proc PyLong_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyLong_Type)
+
+proc PyLong_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyLong_Type)
+
+proc PyTuple_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyTuple_Type)
+
+proc PyTuple_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyTuple_Type)
+
+proc PyInstance_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyInstance_Type)
+
+proc PyClass_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyClass_Type)
+
+proc PyMethod_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyMethod_Type)
+
+proc PyList_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyList_Type)
+
+proc PyList_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyList_Type)
+
+proc PyDict_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyDict_Type)
+
+proc PyDict_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyDict_Type)
+
+proc PyModule_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyModule_Type)
+
+proc PyModule_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PyModule_Type)
+
+proc PySlice_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PySlice_Type)
+
+proc PyFunction_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and
+      ((obj.ob_type == PyCFunction_Type) or
+      (obj.ob_type == PyFunction_Type))
+
+proc PyUnicode_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyUnicode_Type)
+
+proc PyUnicode_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyUnicode_Type)
+
+proc PyType_IS_GC(t: PPyTypeObject): bool = 
+  Result = PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC)
+
+proc PyObject_IS_GC(obj: PPyObject): bool = 
+  Result = PyType_IS_GC(obj.ob_type) and
+      ((obj.ob_type.tp_is_gc == nil) or (obj.ob_type.tp_is_gc(obj) == 1))
+
+proc PyBool_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyBool_Type)
+
+proc PyBaseString_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyBaseString_Type)
+
+proc PyEnum_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PyEnum_Type)
+
+proc PyObject_TypeCheck(obj: PPyObject, t: PPyTypeObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == t)
+  if not Result and (obj != nil) and (t != nil): 
+    Result = PyType_IsSubtype(obj.ob_type, t) == 1
+  
+proc Py_InitModule(name: cstring, md: PPyMethodDef): PPyObject = 
+  result = Py_InitModule4(name, md, nil, nil, 1012)
+
+proc PyType_HasFeature(AType: PPyTypeObject, AFlag: int): bool = 
+  #(((t)->tp_flags & (f)) != 0)
+  Result = (AType.tp_flags and AFlag) != 0
+
+proc init(lib: TLibHandle) = 
+  Py_DebugFlag = cast[PInt](symAddr(lib, "Py_DebugFlag"))
+  Py_VerboseFlag = cast[PInt](symAddr(lib, "Py_VerboseFlag"))
+  Py_InteractiveFlag = cast[PInt](symAddr(lib, "Py_InteractiveFlag"))
+  Py_OptimizeFlag = cast[PInt](symAddr(lib, "Py_OptimizeFlag"))
+  Py_NoSiteFlag = cast[PInt](symAddr(lib, "Py_NoSiteFlag"))
+  Py_UseClassExceptionsFlag = cast[PInt](symAddr(lib, "Py_UseClassExceptionsFlag"))
+  Py_FrozenFlag = cast[PInt](symAddr(lib, "Py_FrozenFlag"))
+  Py_TabcheckFlag = cast[PInt](symAddr(lib, "Py_TabcheckFlag"))
+  Py_UnicodeFlag = cast[PInt](symAddr(lib, "Py_UnicodeFlag"))
+  Py_IgnoreEnvironmentFlag = cast[PInt](symAddr(lib, "Py_IgnoreEnvironmentFlag"))
+  Py_DivisionWarningFlag = cast[PInt](symAddr(lib, "Py_DivisionWarningFlag"))
+  Py_None = cast[PPyObject](symAddr(lib, "_Py_NoneStruct"))
+  Py_Ellipsis = cast[PPyObject](symAddr(lib, "_Py_EllipsisObject"))
+  Py_False = cast[PPyIntObject](symAddr(lib, "_Py_ZeroStruct"))
+  Py_True = cast[PPyIntObject](symAddr(lib, "_Py_TrueStruct"))
+  Py_NotImplemented = cast[PPyObject](symAddr(lib, "_Py_NotImplementedStruct"))
+  PyImport_FrozenModules = cast[PP_frozen](symAddr(lib, "PyImport_FrozenModules"))
+  PyExc_AttributeError = cast[PPPyObject](symAddr(lib, "PyExc_AttributeError"))
+  PyExc_EOFError = cast[PPPyObject](symAddr(lib, "PyExc_EOFError"))
+  PyExc_IOError = cast[PPPyObject](symAddr(lib, "PyExc_IOError"))
+  PyExc_ImportError = cast[PPPyObject](symAddr(lib, "PyExc_ImportError"))
+  PyExc_IndexError = cast[PPPyObject](symAddr(lib, "PyExc_IndexError"))
+  PyExc_KeyError = cast[PPPyObject](symAddr(lib, "PyExc_KeyError"))
+  PyExc_KeyboardInterrupt = cast[PPPyObject](symAddr(lib, "PyExc_KeyboardInterrupt"))
+  PyExc_MemoryError = cast[PPPyObject](symAddr(lib, "PyExc_MemoryError"))
+  PyExc_NameError = cast[PPPyObject](symAddr(lib, "PyExc_NameError"))
+  PyExc_OverflowError = cast[PPPyObject](symAddr(lib, "PyExc_OverflowError"))
+  PyExc_RuntimeError = cast[PPPyObject](symAddr(lib, "PyExc_RuntimeError"))
+  PyExc_SyntaxError = cast[PPPyObject](symAddr(lib, "PyExc_SyntaxError"))
+  PyExc_SystemError = cast[PPPyObject](symAddr(lib, "PyExc_SystemError"))
+  PyExc_SystemExit = cast[PPPyObject](symAddr(lib, "PyExc_SystemExit"))
+  PyExc_TypeError = cast[PPPyObject](symAddr(lib, "PyExc_TypeError"))
+  PyExc_ValueError = cast[PPPyObject](symAddr(lib, "PyExc_ValueError"))
+  PyExc_ZeroDivisionError = cast[PPPyObject](symAddr(lib, "PyExc_ZeroDivisionError"))
+  PyExc_ArithmeticError = cast[PPPyObject](symAddr(lib, "PyExc_ArithmeticError"))
+  PyExc_Exception = cast[PPPyObject](symAddr(lib, "PyExc_Exception"))
+  PyExc_FloatingPointError = cast[PPPyObject](symAddr(lib, "PyExc_FloatingPointError"))
+  PyExc_LookupError = cast[PPPyObject](symAddr(lib, "PyExc_LookupError"))
+  PyExc_StandardError = cast[PPPyObject](symAddr(lib, "PyExc_StandardError"))
+  PyExc_AssertionError = cast[PPPyObject](symAddr(lib, "PyExc_AssertionError"))
+  PyExc_EnvironmentError = cast[PPPyObject](symAddr(lib, "PyExc_EnvironmentError"))
+  PyExc_IndentationError = cast[PPPyObject](symAddr(lib, "PyExc_IndentationError"))
+  PyExc_MemoryErrorInst = cast[PPPyObject](symAddr(lib, "PyExc_MemoryErrorInst"))
+  PyExc_NotImplementedError = cast[PPPyObject](symAddr(lib, "PyExc_NotImplementedError"))
+  PyExc_OSError = cast[PPPyObject](symAddr(lib, "PyExc_OSError"))
+  PyExc_TabError = cast[PPPyObject](symAddr(lib, "PyExc_TabError"))
+  PyExc_UnboundLocalError = cast[PPPyObject](symAddr(lib, "PyExc_UnboundLocalError"))
+  PyExc_UnicodeError = cast[PPPyObject](symAddr(lib, "PyExc_UnicodeError"))
+  PyExc_Warning = cast[PPPyObject](symAddr(lib, "PyExc_Warning"))
+  PyExc_DeprecationWarning = cast[PPPyObject](symAddr(lib, "PyExc_DeprecationWarning"))
+  PyExc_RuntimeWarning = cast[PPPyObject](symAddr(lib, "PyExc_RuntimeWarning"))
+  PyExc_SyntaxWarning = cast[PPPyObject](symAddr(lib, "PyExc_SyntaxWarning"))
+  PyExc_UserWarning = cast[PPPyObject](symAddr(lib, "PyExc_UserWarning"))
+  PyExc_OverflowWarning = cast[PPPyObject](symAddr(lib, "PyExc_OverflowWarning"))
+  PyExc_ReferenceError = cast[PPPyObject](symAddr(lib, "PyExc_ReferenceError"))
+  PyExc_StopIteration = cast[PPPyObject](symAddr(lib, "PyExc_StopIteration"))
+  PyExc_FutureWarning = cast[PPPyObject](symAddr(lib, "PyExc_FutureWarning"))
+  PyExc_PendingDeprecationWarning = cast[PPPyObject](symAddr(lib, 
+      "PyExc_PendingDeprecationWarning"))
+  PyExc_UnicodeDecodeError = cast[PPPyObject](symAddr(lib, "PyExc_UnicodeDecodeError"))
+  PyExc_UnicodeEncodeError = cast[PPPyObject](symAddr(lib, "PyExc_UnicodeEncodeError"))
+  PyExc_UnicodeTranslateError = cast[PPPyObject](symAddr(lib, "PyExc_UnicodeTranslateError"))
+  PyType_Type = cast[PPyTypeObject](symAddr(lib, "PyType_Type"))
+  PyCFunction_Type = cast[PPyTypeObject](symAddr(lib, "PyCFunction_Type"))
+  PyCObject_Type = cast[PPyTypeObject](symAddr(lib, "PyCObject_Type"))
+  PyClass_Type = cast[PPyTypeObject](symAddr(lib, "PyClass_Type"))
+  PyCode_Type = cast[PPyTypeObject](symAddr(lib, "PyCode_Type"))
+  PyComplex_Type = cast[PPyTypeObject](symAddr(lib, "PyComplex_Type"))
+  PyDict_Type = cast[PPyTypeObject](symAddr(lib, "PyDict_Type"))
+  PyFile_Type = cast[PPyTypeObject](symAddr(lib, "PyFile_Type"))
+  PyFloat_Type = cast[PPyTypeObject](symAddr(lib, "PyFloat_Type"))
+  PyFrame_Type = cast[PPyTypeObject](symAddr(lib, "PyFrame_Type"))
+  PyFunction_Type = cast[PPyTypeObject](symAddr(lib, "PyFunction_Type"))
+  PyInstance_Type = cast[PPyTypeObject](symAddr(lib, "PyInstance_Type"))
+  PyInt_Type = cast[PPyTypeObject](symAddr(lib, "PyInt_Type"))
+  PyList_Type = cast[PPyTypeObject](symAddr(lib, "PyList_Type"))
+  PyLong_Type = cast[PPyTypeObject](symAddr(lib, "PyLong_Type"))
+  PyMethod_Type = cast[PPyTypeObject](symAddr(lib, "PyMethod_Type"))
+  PyModule_Type = cast[PPyTypeObject](symAddr(lib, "PyModule_Type"))
+  PyObject_Type = cast[PPyTypeObject](symAddr(lib, "PyObject_Type"))
+  PyRange_Type = cast[PPyTypeObject](symAddr(lib, "PyRange_Type"))
+  PySlice_Type = cast[PPyTypeObject](symAddr(lib, "PySlice_Type"))
+  PyString_Type = cast[PPyTypeObject](symAddr(lib, "PyString_Type"))
+  PyTuple_Type = cast[PPyTypeObject](symAddr(lib, "PyTuple_Type"))
+  PyUnicode_Type = cast[PPyTypeObject](symAddr(lib, "PyUnicode_Type"))
+  PyBaseObject_Type = cast[PPyTypeObject](symAddr(lib, "PyBaseObject_Type"))
+  PyBuffer_Type = cast[PPyTypeObject](symAddr(lib, "PyBuffer_Type"))
+  PyCallIter_Type = cast[PPyTypeObject](symAddr(lib, "PyCallIter_Type"))
+  PyCell_Type = cast[PPyTypeObject](symAddr(lib, "PyCell_Type"))
+  PyClassMethod_Type = cast[PPyTypeObject](symAddr(lib, "PyClassMethod_Type"))
+  PyProperty_Type = cast[PPyTypeObject](symAddr(lib, "PyProperty_Type"))
+  PySeqIter_Type = cast[PPyTypeObject](symAddr(lib, "PySeqIter_Type"))
+  PyStaticMethod_Type = cast[PPyTypeObject](symAddr(lib, "PyStaticMethod_Type"))
+  PySuper_Type = cast[PPyTypeObject](symAddr(lib, "PySuper_Type"))
+  PySymtableEntry_Type = cast[PPyTypeObject](symAddr(lib, "PySymtableEntry_Type"))
+  PyTraceBack_Type = cast[PPyTypeObject](symAddr(lib, "PyTraceBack_Type"))
+  PyWrapperDescr_Type = cast[PPyTypeObject](symAddr(lib, "PyWrapperDescr_Type"))
+  PyBaseString_Type = cast[PPyTypeObject](symAddr(lib, "PyBaseString_Type"))
+  PyBool_Type = cast[PPyTypeObject](symAddr(lib, "PyBool_Type"))
+  PyEnum_Type = cast[PPyTypeObject](symAddr(lib, "PyEnum_Type"))
+
+# Unfortunately we have to duplicate the loading mechanism here, because Nimrod
+# does not support variables from dynamic libraries. Well designed API's don't
+# require this anyway. Python is an exception.
+
+var
+  lib: TLibHandle
+
+when defined(windows): 
+  const
+    LibNames = ["python26.dll", "python25.dll", 
+      "python24.dll", "python23.dll", "python22.dll", "python21.dll", 
+      "python20.dll", "python16.dll", "python15.dll"]
+elif defined(macosx):
+  const
+    LibNames = ["libpython2.6.dylib", "libpython2.5.dylib", 
+      "libpython2.4.dylib", "libpython2.3.dylib", "libpython2.2.dylib", 
+      "libpython2.1.dylib", "libpython2.0.dylib",
+      "libpython1.6.dylib", "libpython1.5.dylib"]
+else: 
+  const
+    LibNames = ["libpython2.6.so" & dllver, 
+      "libpython2.5.so" & dllver, 
+      "libpython2.4.so" & dllver, 
+      "libpython2.3.so" & dllver, 
+      "libpython2.2.so" & dllver, 
+      "libpython2.1.so" & dllver, 
+      "libpython2.0.so" & dllver,
+      "libpython1.6.so" & dllver, 
+      "libpython1.5.so" & dllver]
+  
+for libName in items(libNames): 
+  lib = loadLib(libName)
+  if lib != nil: break
+
+if lib == nil: quit("could not load python library")
+init(lib)
+
diff --git a/lib/base/sdl/sdl.nim b/lib/wrappers/sdl/sdl.nim
index 7d2b6ba26..7d2b6ba26 100644
--- a/lib/base/sdl/sdl.nim
+++ b/lib/wrappers/sdl/sdl.nim
diff --git a/lib/base/sdl/sdl_gfx.nim b/lib/wrappers/sdl/sdl_gfx.nim
index 8ae8eca0b..8ae8eca0b 100644
--- a/lib/base/sdl/sdl_gfx.nim
+++ b/lib/wrappers/sdl/sdl_gfx.nim
diff --git a/lib/base/sdl/sdl_image.nim b/lib/wrappers/sdl/sdl_image.nim
index a15afd575..a15afd575 100644
--- a/lib/base/sdl/sdl_image.nim
+++ b/lib/wrappers/sdl/sdl_image.nim
diff --git a/lib/base/sdl/sdl_mixer.nim b/lib/wrappers/sdl/sdl_mixer.nim
index f840dc52a..f840dc52a 100644
--- a/lib/base/sdl/sdl_mixer.nim
+++ b/lib/wrappers/sdl/sdl_mixer.nim
diff --git a/lib/base/sdl/sdl_mixer_nosmpeg.nim b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim
index 6282b5edc..6282b5edc 100644
--- a/lib/base/sdl/sdl_mixer_nosmpeg.nim
+++ b/lib/wrappers/sdl/sdl_mixer_nosmpeg.nim
diff --git a/lib/base/sdl/sdl_net.nim b/lib/wrappers/sdl/sdl_net.nim
index f27a674ae..f27a674ae 100644
--- a/lib/base/sdl/sdl_net.nim
+++ b/lib/wrappers/sdl/sdl_net.nim
diff --git a/lib/base/sdl/sdl_ttf.nim b/lib/wrappers/sdl/sdl_ttf.nim
index 724c2f634..724c2f634 100644
--- a/lib/base/sdl/sdl_ttf.nim
+++ b/lib/wrappers/sdl/sdl_ttf.nim
diff --git a/lib/base/sdl/sdlutils.pas b/lib/wrappers/sdl/sdlutils.pas
index e4206e935..e4206e935 100644
--- a/lib/base/sdl/sdlutils.pas
+++ b/lib/wrappers/sdl/sdlutils.pas
diff --git a/lib/base/sdl/smpeg.nim b/lib/wrappers/sdl/smpeg.nim
index ada0ed57c..ada0ed57c 100644
--- a/lib/base/sdl/smpeg.nim
+++ b/lib/wrappers/sdl/smpeg.nim
diff --git a/lib/base/sqlite3.nim b/lib/wrappers/sqlite3.nim
index 9a97330ec..9a97330ec 100644
--- a/lib/base/sqlite3.nim
+++ b/lib/wrappers/sqlite3.nim
diff --git a/lib/wrappers/tcl.nim b/lib/wrappers/tcl.nim
new file mode 100644
index 000000000..3539bf92e
--- /dev/null
+++ b/lib/wrappers/tcl.nim
@@ -0,0 +1,855 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2009 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module is a wrapper for the TCL programming language.
+
+#
+#  tcl.h --
+# 
+#  This header file describes the externally-visible facilities of the Tcl
+#  interpreter.
+# 
+#  Translated to Pascal Copyright (c) 2002 by Max Artemev
+#  aka Bert Raccoon (bert@furry.ru, bert_raccoon@freemail.ru)
+# 
+# 
+#  Copyright (c) 1998-2000 by Scriptics Corporation.
+#  Copyright (c) 1994-1998 Sun Microsystems, Inc.
+#  Copyright (c) 1993-1996 Lucent Technologies.
+#  Copyright (c) 1987-1994 John Ousterhout, The Regents of the
+#                          University of California, Berkeley.
+# 
+#  ***********************************************************************
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#  ***********************************************************************
+# 
+
+when defined(WIN32): 
+  const dllName = "tcl(85|84|83|82|81|80).dll"
+elif defined(macosx): 
+  const dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).dynlib"
+else:
+  const dllName = "libtcl(8.5|8.4|8.3|8.2|8.1).so.(1|0)"
+
+const 
+  TCL_DESTROYED* = 0xDEADDEAD
+  TCL_OK* = 0
+  TCL_ERROR* = 1
+  TCL_RETURN* = 2
+  TCL_BREAK* = 3
+  TCL_CONTINUE* = 4
+  TCL_RESULT_SIZE* = 200
+  MAX_ARGV* = 0x00007FFF
+  TCL_VERSION_MAJOR* = 0
+  TCL_VERSION_MINOR* = 0
+  TCL_NO_EVAL* = 0x00010000
+  TCL_EVAL_GLOBAL* = 0x00020000 #* Flag values passed to variable-related procedures. *
+  TCL_GLOBAL_ONLY* = 1
+  TCL_NAMESPACE_ONLY* = 2
+  TCL_APPEND_VALUE* = 4
+  TCL_LIST_ELEMENT* = 8
+  TCL_TRACE_READS* = 0x00000010
+  TCL_TRACE_WRITES* = 0x00000020
+  TCL_TRACE_UNSETS* = 0x00000040
+  TCL_TRACE_DESTROYED* = 0x00000080
+  TCL_INTERP_DESTROYED* = 0x00000100
+  TCL_LEAVE_ERR_MSG* = 0x00000200
+  TCL_PARSE_PART1* = 0x00000400 #* Types for linked variables: *
+  TCL_LINK_INT* = 1
+  TCL_LINK_DOUBLE* = 2
+  TCL_LINK_BOOLEAN* = 3
+  TCL_LINK_STRING* = 4
+  TCL_LINK_READ_ONLY* = 0x00000080
+  TCL_SMALL_HASH_TABLE* = 4   #* Hash Table *
+  TCL_STRING_KEYS* = 0
+  TCL_ONE_WORD_KEYS* = 1      #* Const/enums Tcl_QueuePosition *
+                              # typedef enum {
+  TCL_QUEUE_TAIL* = 0
+  TCL_QUEUE_HEAD* = 1
+  TCL_QUEUE_MARK* = 2         #} Tcl_QueuePosition;
+                              # Event Flags
+  TCL_DONT_WAIT* = 1 shl 1
+  TCL_WINDOW_EVENTS* = 1 shl 2
+  TCL_FILE_EVENTS* = 1 shl 3
+  TCL_TIMER_EVENTS* = 1 shl 4
+  TCL_IDLE_EVENTS* = 1 shl 5  #* WAS 0x10 ???? *
+  TCL_ALL_EVENTS* = not TCL_DONT_WAIT 
+
+  TCL_VOLATILE* = 1
+  TCL_STATIC* = 0
+  TCL_DYNAMIC* = 3            # Channel
+  TCL_STDIN* = 1 shl 1
+  TCL_STDOUT* = 1 shl 2
+  TCL_STDERR* = 1 shl 3
+  TCL_ENFORCE_MODE* = 1 shl 4
+  TCL_READABLE* = 1 shl 1
+  TCL_WRITABLE* = 1 shl 2
+  TCL_EXCEPTION* = 1 shl 3    #* POSIX *
+  EPERM* = 1 # Operation not permitted; only the owner of the file (or other
+             # resource) or processes with special privileges can perform the
+             # operation.
+             #
+  ENOENT* = 2 # No such file or directory.  This is a "file doesn't exist" error
+              # for ordinary files that are referenced in contexts where they are
+              # expected to already exist.
+              #
+  ESRCH* = 3                  #* No process matches the specified process ID. *
+  EINTR* = 4 #* Interrupted function call; an asynchronous signal occurred and
+             # * prevented completion of the call.  When this happens, you should
+             # * try the call again.
+             # *
+  EIO* = 5                    #* Input/output error; usually used for physical read or write errors. *
+  ENXIO* = 6 #* No such device or address.  The system tried to use the device
+             # * represented by a file you specified, and it couldn't find the
+             # * device.  This can mean that the device file was installed
+             # * incorrectly, or that the physical device is missing or not
+             # * correctly attached to the computer.
+             # *
+  E2BIG* = 7 #* Argument list too long; used when the arguments passed to a new
+             # * program being executed with one of the `exec' functions (*note
+             # * Executing a File::.) occupy too much memory space.  This condition
+             # * never arises in the GNU system.
+             # *
+  ENOEXEC* = 8 #* Invalid executable file format.  This condition is detected by the
+               # * `exec' functions; see *Note Executing a File::.
+               # *
+  EBADF* = 9 #* Bad file descriptor; for example, I/O on a descriptor that has been
+             # * closed or reading from a descriptor open only for writing (or vice
+             # * versa).
+             # *
+  ECHILD* = 10 #* There are no child processes.  This error happens on operations
+               # * that are supposed to manipulate child processes, when there aren't
+               # * any processes to manipulate.
+               # *
+  EDEADLK* = 11 #* Deadlock avoided; allocating a system resource would have resulted
+                # * in a deadlock situation.  The system does not guarantee that it
+                # * will notice all such situations.  This error means you got lucky
+                # * and the system noticed; it might just hang.  *Note File Locks::,
+                # * for an example.
+                # *
+  ENOMEM* = 12 #* No memory available.  The system cannot allocate more virtual
+               # * memory because its capacity is full.
+               # *
+  EACCES* = 13 #* Permission denied; the file permissions do not allow the attempted
+               # * operation.
+               # *
+  EFAULT* = 14 #* Bad address; an invalid pointer was detected.  In the GNU system,
+               # * this error never happens; you get a signal instead.
+               # *
+  ENOTBLK* = 15 #* A file that isn't a block special file was given in a situation
+                # * that requires one.  For example, trying to mount an ordinary file
+                # * as a file system in Unix gives this error.
+                # *
+  EBUSY* = 16 #* Resource busy; a system resource that can't be shared is already
+              # * in use.  For example, if you try to delete a file that is the root
+              # * of a currently mounted filesystem, you get this error.
+              # *
+  EEXIST* = 17 #* File exists; an existing file was specified in a context where it
+               # * only makes sense to specify a new file.
+               # *
+  EXDEV* = 18 #* An attempt to make an improper link across file systems was
+              # * detected.  This happens not only when you use `link' (*note Hard
+              # * Links::.) but also when you rename a file with `rename' (*note
+              # * Renaming Files::.).
+              # *
+  ENODEV* = 19 #* The wrong type of device was given to a function that expects a
+               # * particular sort of device.
+               # *
+  ENOTDIR* = 20 #* A file that isn't a directory was specified when a directory is
+                # * required.
+                # *
+  EISDIR* = 21 #* File is a directory; you cannot open a directory for writing, or
+               # * create or remove hard links to it.
+               # *
+  EINVAL* = 22 #* Invalid argument.  This is used to indicate various kinds of
+               # * problems with passing the wrong argument to a library function.
+               # *
+  EMFILE* = 24 #* The current process has too many files open and can't open any
+               # * more.  Duplicate descriptors do count toward this limit.
+               # *
+               # * In BSD and GNU, the number of open files is controlled by a
+               # * resource limit that can usually be increased.  If you get this
+               # * error, you might want to increase the `RLIMIT_NOFILE' limit or
+               # * make it unlimited; *note Limits on Resources::..
+               # *
+  ENFILE* = 23 #* There are too many distinct file openings in the entire system.
+               # * Note that any number of linked channels count as just one file
+               # * opening; see *Note Linked Channels::.  This error never occurs in
+               # * the GNU system.
+               # *
+  ENOTTY* = 25 #* Inappropriate I/O control operation, such as trying to set terminal
+               # * modes on an ordinary file.
+               # *
+  ETXTBSY* = 26 #* An attempt to execute a file that is currently open for writing, or
+                # * write to a file that is currently being executed.  Often using a
+                # * debugger to run a program is considered having it open for writing
+                # * and will cause this error.  (The name stands for "text file
+                # * busy".)  This is not an error in the GNU system; the text is
+                # * copied as necessary.
+                # *
+  EFBIG* = 27 #* File too big; the size of a file would be larger than allowed by
+              # * the system.
+              # *
+  ENOSPC* = 28 #* No space left on device; write operation on a file failed because
+               # * the disk is full.
+               # *
+  ESPIPE* = 29                #* Invalid seek operation (such as on a pipe).  *
+  EROFS* = 30                 #* An attempt was made to modify something on a read-only file system.  *
+  EMLINK* = 31 #* Too many links; the link count of a single file would become too
+               # * large.  `rename' can cause this error if the file being renamed
+               # * already has as many links as it can take (*note Renaming Files::.).
+               # *
+  EPIPE* = 32 #* Broken pipe; there is no process reading from the other end of a
+              # * pipe.  Every library function that returns this error code also
+              # * generates a `SIGPIPE' signal; this signal terminates the program
+              # * if not handled or blocked.  Thus, your program will never actually
+              # * see `EPIPE' unless it has handled or blocked `SIGPIPE'.
+              # *
+  EDOM* = 33 #* Domain error; used by mathematical functions when an argument
+             # * value does not fall into the domain over which the function is
+             # * defined.
+             # *
+  ERANGE* = 34 #* Range error; used by mathematical functions when the result value
+               # * is not representable because of overflow or underflow.
+               # *
+  EAGAIN* = 35 #* Resource temporarily unavailable; the call might work if you try
+               # * again later.  The macro `EWOULDBLOCK' is another name for `EAGAIN';
+               # * they are always the same in the GNU C library.
+               # *
+  EWOULDBLOCK* = EAGAIN #* In the GNU C library, this is another name for `EAGAIN' (above).
+                        # * The values are always the same, on every operating system.
+                        # * C libraries in many older Unix systems have `EWOULDBLOCK' as a
+                        # * separate error code.
+                        # *
+  EINPROGRESS* = 36 #* An operation that cannot complete immediately was initiated on an
+                    # * object that has non-blocking mode selected.  Some functions that
+                    # * must always block (such as `connect'; *note Connecting::.) never
+                    # * return `EAGAIN'.  Instead, they return `EINPROGRESS' to indicate
+                    # * that the operation has begun and will take some time.  Attempts to
+                    # * manipulate the object before the call completes return `EALREADY'.
+                    # * You can use the `select' function to find out when the pending
+                    # * operation has completed; *note Waiting for I/O::..
+                    # *
+  EALREADY* = 37 #* An operation is already in progress on an object that has
+                 # * non-blocking mode selected.
+                 # *
+  ENOTSOCK* = 38              #* A file that isn't a socket was specified when a socket is required.  *
+  EDESTADDRREQ* = 39 #* No default destination address was set for the socket.  You get
+                     # * this error when you try to transmit data over a connectionless
+                     # * socket, without first specifying a destination for the data with
+                     # * `connect'.
+                     # *
+  EMSGSIZE* = 40 #* The size of a message sent on a socket was larger than the
+                 # * supported maximum size.
+                 # *
+  EPROTOTYPE* = 41 #* The socket type does not support the requested communications
+                   # * protocol.
+                   # *
+  ENOPROTOOPT* = 42 #* You specified a socket option that doesn't make sense for the
+                    # * particular protocol being used by the socket.  *Note Socket
+                    # * Options::.
+                    # *
+  EPROTONOSUPPORT* = 43 #* The socket domain does not support the requested communications
+                        # * protocol (perhaps because the requested protocol is completely
+                        # * invalid.) *Note Creating a Socket::.
+                        # *
+  ESOCKTNOSUPPORT* = 44       #* The socket type is not supported.  *
+  EOPNOTSUPP* = 45 #* The operation you requested is not supported.  Some socket
+                   # * functions don't make sense for all types of sockets, and others
+                   # * may not be implemented for all communications protocols.  In the
+                   # * GNU system, this error can happen for many calls when the object
+                   # * does not support the particular operation; it is a generic
+                   # * indication that the server knows nothing to do for that call.
+                   # *
+  EPFNOSUPPORT* = 46 #* The socket communications protocol family you requested is not
+                     # * supported.
+                     # *
+  EAFNOSUPPORT* = 47 #* The address family specified for a socket is not supported; it is
+                     # * inconsistent with the protocol being used on the socket.  *Note
+                     # * Sockets::.
+                     # *
+  EADDRINUSE* = 48 #* The requested socket address is already in use.  *Note Socket
+                   # * Addresses::.
+                   # *
+  EADDRNOTAVAIL* = 49 #* The requested socket address is not available; for example, you
+                      # * tried to give a socket a name that doesn't match the local host
+                      # * name.  *Note Socket Addresses::.
+                      # *
+  ENETDOWN* = 50              #* A socket operation failed because the network was down.  *
+  ENETUNREACH* = 51 #* A socket operation failed because the subnet containing the remote
+                    # * host was unreachable.
+                    # *
+  ENETRESET* = 52             #* A network connection was reset because the remote host crashed.  *
+  ECONNABORTED* = 53          #* A network connection was aborted locally. *
+  ECONNRESET* = 54 #* A network connection was closed for reasons outside the control of
+                   # * the local host, such as by the remote machine rebooting or an
+                   # * unrecoverable protocol violation.
+                   # *
+  ENOBUFS* = 55 #* The kernel's buffers for I/O operations are all in use.  In GNU,
+                # * this error is always synonymous with `ENOMEM'; you may get one or
+                # * the other from network operations.
+                # *
+  EISCONN* = 56 #* You tried to connect a socket that is already connected.  *Note
+                # * Connecting::.
+                # *
+  ENOTCONN* = 57 #* The socket is not connected to anything.  You get this error when
+                 # * you try to transmit data over a socket, without first specifying a
+                 # * destination for the data.  For a connectionless socket (for
+                 # * datagram protocols, such as UDP), you get `EDESTADDRREQ' instead.
+                 # *
+  ESHUTDOWN* = 58             #* The socket has already been shut down.  *
+  ETOOMANYREFS* = 59          #* ???  *
+  ETIMEDOUT* = 60 #* A socket operation with a specified timeout received no response
+                  # * during the timeout period.
+                  # *
+  ECONNREFUSED* = 61 #* A remote host refused to allow the network connection (typically
+                     # * because it is not running the requested service).
+                     # *
+  ELOOP* = 62 #* Too many levels of symbolic links were encountered in looking up a
+              # * file name.  This often indicates a cycle of symbolic links.
+              # *
+  ENAMETOOLONG* = 63 #* Filename too long (longer than `PATH_MAX'; *note Limits for
+                     # * Files::.) or host name too long (in `gethostname' or
+                     # * `sethostname'; *note Host Identification::.).
+                     # *
+  EHOSTDOWN* = 64             #* The remote host for a requested network connection is down.  *
+  EHOSTUNREACH* = 65 #* The remote host for a requested network connection is not
+                     # * reachable.
+                     # *
+  ENOTEMPTY* = 66 #* Directory not empty, where an empty directory was expected.
+                  # * Typically, this error occurs when you are trying to delete a
+                  # * directory.
+                  # *
+  EPROCLIM* = 67 #* This means that the per-user limit on new process would be
+                 # * exceeded by an attempted `fork'.  *Note Limits on Resources::, for
+                 # * details on the `RLIMIT_NPROC' limit.
+                 # *
+  EUSERS* = 68                #* The file quota system is confused because there are too many users.  *
+  EDQUOT* = 69                #* The user's disk quota was exceeded.  *
+  ESTALE* = 70 #* Stale NFS file handle.  This indicates an internal confusion in
+               # * the NFS system which is due to file system rearrangements on the
+               # * server host.  Repairing this condition usually requires unmounting
+               # * and remounting the NFS file system on the local host.
+               # *
+  EREMOTE* = 71 #* An attempt was made to NFS-mount a remote file system with a file
+                # * name that already specifies an NFS-mounted file.  (This is an
+                # * error on some operating systems, but we expect it to work properly
+                # * on the GNU system, making this error code impossible.)
+                # *
+  EBADRPC* = 72               #* ???  *
+  ERPCMISMATCH* = 73          #* ???  *
+  EPROGUNAVAIL* = 74          #* ???  *
+  EPROGMISMATCH* = 75         #* ???  *
+  EPROCUNAVAIL* = 76          #* ???  *
+  ENOLCK* = 77 #* No locks available.  This is used by the file locking facilities;
+               # * see *Note File Locks::.  This error is never generated by the GNU
+               # * system, but it can result from an operation to an NFS server
+               # * running another operating system.
+               # *
+  ENOSYS* = 78 #* Function not implemented.  Some functions have commands or options
+               # * defined that might not be supported in all implementations, and
+               # * this is the kind of error you get if you request them and they are
+               # * not supported.
+               # *
+  EFTYPE* = 79 #* Inappropriate file type or format.  The file was the wrong type
+               # * for the operation, or a data file had the wrong format.
+               # * On some systems `chmod' returns this error if you try to set the
+               # * sticky bit on a non-directory file; *note Setting Permissions::..
+               # *
+
+type 
+  Tcl_Argv* = cstringArray
+  Tcl_ClientData* = pointer
+  Tcl_FreeProc* = proc (theBlock: pointer){.cdecl.}
+  PTcl_Interp* = ptr Tcl_Interp
+  Tcl_Interp*{.final.} = object  #*  Event Definitions  *
+    result*: cstring #* Do not access this directly. Use
+                     #                          * Tcl_GetStringResult since result
+                     #                          * may be pointing to an object
+                     #                          *
+    freeProc*: Tcl_FreeProc
+    errorLine*: int
+
+  TTcl_EventSetupProc* = proc (clientData: Tcl_ClientData, flags: int){.cdecl.}
+  TTcl_EventCheckProc* = TTcl_EventSetupProc
+  PTcl_Event* = ptr Tcl_Event
+  TTcl_EventProc* = proc (evPtr: PTcl_Event, flags: int): int{.cdecl.}
+  Tcl_Event*{.final.} = object 
+    prc*: TTcl_EventProc
+    nextPtr*: PTcl_Event
+    ClientData*: TObject      #* ClientData is just pointer.*
+  
+  PTcl_Time* = ptr Tcl_Time
+  Tcl_Time*{.final.} = object 
+    sec*: int32               # * Seconds. * 
+    usec*: int32              # * Microseconds. * 
+  
+  Tcl_TimerToken* = pointer
+  PInteger* = ptr int
+  PTcl_HashTable* = pointer
+  PTcl_HashEntry* = ptr Tcl_HashEntry
+  PPTcl_HashEntry* = ptr PTcl_HashEntry
+  Tcl_HashEntry*{.final.} = object  
+    nextPtr*: PTcl_HashEntry
+    tablePtr*: PTcl_HashTable
+    bucketPtr*: PPTcl_HashEntry
+    clientData*: Tcl_ClientData
+    key*: cstring
+
+  Tcl_HashFindProc* = proc (tablePtr: PTcl_HashTable, key: cstring): PTcl_HashEntry{.
+      cdecl.}
+  Tcl_HashCreateProc* = proc (tablePtr: PTcl_HashTable, key: cstring, 
+                              newPtr: PInteger): PTcl_HashEntry{.cdecl.}
+  PHashTable* = ptr Tcl_HashTable
+  Tcl_HashTable*{.final.} = object 
+    buckets*: ppTcl_HashEntry
+    staticBuckets*: array[0..TCL_SMALL_HASH_TABLE - 1, PTcl_HashEntry]
+    numBuckets*: int
+    numEntries*: int
+    rebuildSize*: int
+    downShift*: int
+    mask*: int
+    keyType*: int
+    findProc*: Tcl_HashFindProc
+    createProc*: Tcl_HashCreateProc
+
+  PTcl_HashSearch* = ptr Tcl_HashSearch
+  Tcl_HashSearch*{.final.} = object 
+    tablePtr*: PTcl_HashTable
+    nextIndex*: int
+    nextEntryPtr*: PTcl_HashEntry
+
+  TTclAppInitProc* = proc (interp: pTcl_Interp): int{.cdecl.}
+  TTclPackageInitProc* = proc (interp: pTcl_Interp): int{.cdecl.}
+  TTclCmdProc* = proc (clientData: Tcl_ClientData, interp: pTcl_Interp, 
+                       argc: int, argv: Tcl_Argv): int{.cdecl.}
+  TTclVarTraceProc* = proc (clientData: Tcl_ClientData, interp: pTcl_Interp, 
+                            varName: cstring, elemName: cstring, flags: int): cstring{.
+      cdecl.}
+  TTclFreeProc* = proc (theBlock: pointer){.cdecl.}
+  TTclInterpDeleteProc* = proc (clientData: Tcl_ClientData, interp: pTcl_Interp){.
+      cdecl.}
+  TTclCmdDeleteProc* = proc (clientData: Tcl_ClientData){.cdecl.}
+  TTclNamespaceDeleteProc* = proc (clientData: Tcl_ClientData){.cdecl.}
+
+const 
+  TCL_DSTRING_STATIC_SIZE* = 200
+
+type 
+  PTcl_DString* = ptr Tcl_DString
+  Tcl_DString*{.final.} = object 
+    str*: cstring
+    len*: int
+    spaceAvl*: int
+    staticSpace*: array[0..TCL_DSTRING_STATIC_SIZE - 1, char]
+
+  PTcl_Channel* = ptr Tcl_Channel
+  Tcl_Channel*{.final.} = object 
+  TTclDriverBlockModeProc* = proc (instanceData: Tcl_ClientData, mode: int): int{.
+      cdecl.}
+  TTclDriverCloseProc* = proc (instanceData: Tcl_ClientData, interp: PTcl_Interp): int{.
+      cdecl.}
+  TTclDriverInputProc* = proc (instanceData: Tcl_ClientData, buf: cstring, 
+                               toRead: int, errorCodePtr: PInteger): int{.cdecl.}
+  TTclDriverOutputProc* = proc (instanceData: Tcl_ClientData, buf: cstring, 
+                                toWrite: int, errorCodePtr: PInteger): int{.
+      cdecl.}
+  TTclDriverSeekProc* = proc (instanceData: Tcl_ClientData, offset: int32, 
+                              mode: int, errorCodePtr: PInteger): int{.cdecl.}
+  TTclDriverSetOptionProc* = proc (instanceData: Tcl_ClientData, 
+                                   interp: PTcl_Interp, optionName: cstring, 
+                                   value: cstring): int{.cdecl.}
+  TTclDriverGetOptionProc* = proc (instanceData: Tcl_ClientData, 
+                                   interp: pTcl_Interp, optionName: cstring, 
+                                   dsPtr: PTcl_DString): int{.cdecl.}
+  TTclDriverWatchProc* = proc (instanceData: Tcl_ClientData, mask: int){.cdecl.}
+  TTclDriverGetHandleProc* = proc (instanceData: Tcl_ClientData, direction: int, 
+                                   handlePtr: var Tcl_ClientData): int{.cdecl.}
+  PTcl_ChannelType* = ptr Tcl_ChannelType
+  Tcl_ChannelType*{.final.} = object 
+    typeName*: cstring
+    blockModeProc*: TTclDriverBlockModeProc
+    closeProc*: TTclDriverCloseProc
+    inputProc*: TTclDriverInputProc
+    ouputProc*: TTclDriverOutputProc
+    seekProc*: TTclDriverSeekProc
+    setOptionProc*: TTclDriverSetOptionProc
+    getOptionProc*: TTclDriverGetOptionProc
+    watchProc*: TTclDriverWatchProc
+    getHandleProc*: TTclDriverGetHandleProc
+
+  TTclChannelProc* = proc (clientData: Tcl_ClientData, mask: int){.cdecl.}
+  PTcl_Obj* = ptr Tcl_Obj
+  PPTcl_Obj* = ptr PTcl_Obj
+  Tcl_Obj*{.final.} = object 
+    refCount*: int            # ...
+  
+  TTclObjCmdProc* = proc (clientData: Tcl_ClientData, interp: PTcl_Interp, 
+                          objc: int, PPObj: PPTcl_Obj): int{.cdecl.}
+  PTcl_Namespace* = ptr Tcl_Namespace
+  Tcl_Namespace*{.final.} = object 
+    name*: cstring
+    fullName*: cstring
+    clientData*: Tcl_ClientData
+    deleteProc*: TTclNamespaceDeleteProc
+    parentPtr*: PTcl_Namespace
+
+  PTcl_CallFrame* = ptr Tcl_CallFrame
+  Tcl_CallFrame*{.final.} = object 
+    nsPtr*: PTcl_Namespace
+    dummy1*: int
+    dummy2*: int
+    dummy3*: cstring
+    dummy4*: cstring
+    dummy5*: cstring
+    dummy6*: int
+    dummy7*: cstring
+    dummy8*: cstring
+    dummy9*: int
+    dummy10*: cstring
+
+  PTcl_CmdInfo* = ptr Tcl_CmdInfo
+  Tcl_CmdInfo*{.final.} = object 
+    isNativeObjectProc*: int
+    objProc*: TTclObjCmdProc
+    objClientData*: Tcl_ClientData
+    prc*: TTclCmdProc
+    clientData*: Tcl_ClientData
+    deleteProc*: TTclCmdDeleteProc
+    deleteData*: Tcl_ClientData
+    namespacePtr*: pTcl_Namespace
+
+  pTcl_Command* = ptr Tcl_Command
+  Tcl_Command*{.final.} = object  #       hPtr            : pTcl_HashEntry;
+                                  #        nsPtr           : pTcl_Namespace;
+                                  #        refCount        : integer;
+                                  #        isCmdEpoch      : integer;
+                                  #        compileProc     : pointer;
+                                  #        objProc         : pointer;
+                                  #        objClientData   : Tcl_ClientData;
+                                  #        proc            : pointer;
+                                  #        clientData      : Tcl_ClientData;
+                                  #        deleteProc      : TTclCmdDeleteProc;
+                                  #        deleteData      : Tcl_ClientData;
+                                  #        deleted         : integer;
+                                  #        importRefPtr    : pointer;
+                                  #
+
+type 
+  TTclPanicProc* = proc (fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8: cstring){.
+      cdecl.}                 # 1/15/97 orig. Tcl style
+  TTclClientDataProc* = proc (clientData: Tcl_ClientData){.cdecl.}
+  TTclIdleProc* = proc (clientData: Tcl_ClientData){.cdecl.}
+  TTclTimerProc* = TTclIdleProc
+  TTclCreateCloseHandler* = proc (channel: pTcl_Channel, 
+                                  prc: TTclClientDataProc, 
+                                  clientData: Tcl_ClientData){.cdecl.}
+  TTclDeleteCloseHandler* = TTclCreateCloseHandler
+  TTclEventDeleteProc* = proc (evPtr: pTcl_Event, clientData: Tcl_ClientData): int{.
+      cdecl.}
+
+proc Tcl_Alloc*(size: int): cstring{.cdecl, dynlib: dllName, importc.}
+proc Tcl_CreateInterp*(): pTcl_Interp{.cdecl, dynlib: dllName, importc.}
+proc Tcl_DeleteInterp*(interp: pTcl_Interp){.cdecl, dynlib: dllName, importc.}
+proc Tcl_ResetResult*(interp: pTcl_Interp){.cdecl, dynlib: dllName, importc.}
+proc Tcl_Eval*(interp: pTcl_Interp, script: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_EvalFile*(interp: pTcl_Interp, filename: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_AddErrorInfo*(interp: pTcl_Interp, message: cstring){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_BackgroundError*(interp: pTcl_Interp){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_CreateCommand*(interp: pTcl_Interp, name: cstring, 
+                        cmdProc: TTclCmdProc, clientData: Tcl_ClientData, 
+                        deleteProc: TTclCmdDeleteProc): pTcl_Command{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DeleteCommand*(interp: pTcl_Interp, name: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CallWhenDeleted*(interp: pTcl_Interp, prc: TTclInterpDeleteProc, 
+                          clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DontCallWhenDeleted*(interp: pTcl_Interp, prc: TTclInterpDeleteProc, 
+                              clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CommandComplete*(cmd: cstring): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_LinkVar*(interp: pTcl_Interp, varName: cstring, varAddr: pointer, 
+                  typ: int): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_UnlinkVar*(interp: pTcl_Interp, varName: cstring){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_TraceVar*(interp: pTcl_Interp, varName: cstring, flags: int, 
+                   prc: TTclVarTraceProc, clientData: Tcl_ClientData): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_TraceVar2*(interp: pTcl_Interp, varName: cstring, elemName: cstring, 
+                    flags: int, prc: TTclVarTraceProc, 
+                    clientData: Tcl_ClientData): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_UntraceVar*(interp: pTcl_Interp, varName: cstring, flags: int, 
+                     prc: TTclVarTraceProc, clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_UntraceVar2*(interp: pTcl_Interp, varName: cstring, elemName: cstring, 
+                      flags: int, prc: TTclVarTraceProc, 
+                      clientData: Tcl_ClientData){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_GetVar*(interp: pTcl_Interp, varName: cstring, flags: int): cstring{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GetVar2*(interp: pTcl_Interp, varName: cstring, elemName: cstring, 
+                  flags: int): cstring{.cdecl, dynlib: dllName, importc.}
+proc Tcl_SetVar*(interp: pTcl_Interp, varName: cstring, newValue: cstring, 
+                 flags: int): cstring{.cdecl, dynlib: dllName, importc.}
+proc Tcl_SetVar2*(interp: pTcl_Interp, varName: cstring, elemName: cstring, 
+                  newValue: cstring, flags: int): cstring{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_UnsetVar*(interp: pTcl_Interp, varName: cstring, flags: int): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_UnsetVar2*(interp: pTcl_Interp, varName: cstring, elemName: cstring, 
+                    flags: int): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_SetResult*(interp: pTcl_Interp, newValue: cstring, 
+                    freeProc: TTclFreeProc){.cdecl, dynlib: dllName, importc.}
+proc Tcl_FirstHashEntry*(hashTbl: pTcl_HashTable, searchInfo: var Tcl_HashSearch): pTcl_HashEntry{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_NextHashEntry*(searchInfo: var Tcl_HashSearch): pTcl_HashEntry{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_InitHashTable*(hashTbl: pTcl_HashTable, keyType: int){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_StringMatch*(str: cstring, pattern: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+
+proc Tcl_GetErrno*(): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_SetErrno*(val: int){.cdecl, dynlib: dllName, importc.}
+proc Tcl_SetPanicProc*(prc: TTclPanicProc){.cdecl, dynlib: dllName, importc.}
+proc Tcl_PkgProvide*(interp: pTcl_Interp, name: cstring, version: cstring): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_StaticPackage*(interp: pTcl_Interp, pkgName: cstring, 
+                        initProc: TTclPackageInitProc, 
+                        safeInitProc: TTclPackageInitProc){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CreateEventSource*(setupProc: TTcl_EventSetupProc, 
+                            checkProc: TTcl_EventCheckProc, 
+                            clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DeleteEventSource*(setupProc: TTcl_EventSetupProc, 
+                            checkProc: TTcl_EventCheckProc, 
+                            clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_QueueEvent*(evPtr: pTcl_Event, pos: int){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_SetMaxBlockTime*(timePtr: pTcl_Time){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_DeleteEvents*(prc: TTclEventDeleteProc, clientData: Tcl_ClientData){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_DoOneEvent*(flags: int): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_DoWhenIdle*(prc: TTclIdleProc, clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CancelIdleCall*(prc: TTclIdleProc, clientData: Tcl_ClientData){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CreateTimerHandler*(milliseconds: int, prc: TTclTimerProc, 
+                             clientData: Tcl_ClientData): Tcl_TimerToken{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DeleteTimerHandler*(token: Tcl_TimerToken){.cdecl, dynlib: dllName, 
+    importc.}
+  #    procedure Tcl_CreateModalTimeout(milliseconds: integer; prc: TTclTimerProc; clientData: Tcl_ClientData); cdecl; external dllName;
+  #    procedure Tcl_DeleteModalTimeout(prc: TTclTimerProc; clientData: Tcl_ClientData); cdecl; external dllName;
+proc Tcl_SplitList*(interp: pTcl_Interp, list: cstring, argcPtr: var int, 
+                    argvPtr: var Tcl_Argv): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_Merge*(argc: int, argv: Tcl_Argv): cstring{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_Free*(p: cstring){.cdecl, dynlib: dllName, importc.}
+proc Tcl_Init*(interp: pTcl_Interp): int{.cdecl, dynlib: dllName, importc.}
+  #    procedure Tcl_InterpDeleteProc(clientData: Tcl_ClientData; interp: pTcl_Interp); cdecl; external dllName;
+proc Tcl_GetAssocData*(interp: pTcl_Interp, key: cstring, 
+                       prc: var TTclInterpDeleteProc): Tcl_ClientData{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DeleteAssocData*(interp: pTcl_Interp, key: cstring){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_SetAssocData*(interp: pTcl_Interp, key: cstring, 
+                       prc: TTclInterpDeleteProc, clientData: Tcl_ClientData){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_IsSafe*(interp: pTcl_Interp): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_MakeSafe*(interp: pTcl_Interp): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_CreateSlave*(interp: pTcl_Interp, slaveName: cstring, isSafe: int): pTcl_Interp{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GetSlave*(interp: pTcl_Interp, slaveName: cstring): pTcl_Interp{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GetMaster*(interp: pTcl_Interp): pTcl_Interp{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GetInterpPath*(askingInterp: pTcl_Interp, slaveInterp: pTcl_Interp): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_CreateAlias*(slaveInterp: pTcl_Interp, srcCmd: cstring, 
+                      targetInterp: pTcl_Interp, targetCmd: cstring, argc: int, 
+                      argv: Tcl_Argv): int{.cdecl, dynlib: dllName, importc.}
+proc Tcl_GetAlias*(interp: pTcl_Interp, srcCmd: cstring, 
+                   targetInterp: var pTcl_Interp, targetCmd: var cstring, 
+                   argc: var int, argv: var Tcl_Argv): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_ExposeCommand*(interp: pTcl_Interp, hiddenCmdName: cstring, 
+                        cmdName: cstring): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_HideCommand*(interp: pTcl_Interp, cmdName: cstring, 
+                      hiddenCmdName: cstring): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_EventuallyFree*(clientData: Tcl_ClientData, freeProc: TTclFreeProc){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_Preserve*(clientData: Tcl_ClientData){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_Release*(clientData: Tcl_ClientData){.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_InterpDeleted*(interp: pTcl_Interp): int{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_GetCommandInfo*(interp: pTcl_Interp, cmdName: cstring, 
+                         info: var Tcl_CmdInfo): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_SetCommandInfo*(interp: pTcl_Interp, cmdName: cstring, 
+                         info: var Tcl_CmdInfo): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_FindExecutable*(path: cstring){.cdecl, dynlib: dllName, importc.}
+proc Tcl_GetStringResult*(interp: pTcl_Interp): cstring{.cdecl, 
+    dynlib: dllName, importc.}
+  #v1.0
+proc Tcl_FindCommand*(interp: pTcl_Interp, cmdName: cstring, 
+                      contextNsPtr: pTcl_Namespace, flags: int): Tcl_Command{.
+    cdecl, dynlib: dllName, importc.}
+  #v1.0
+proc Tcl_DeleteCommandFromToken*(interp: pTcl_Interp, cmd: pTcl_Command): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_CreateNamespace*(interp: pTcl_Interp, name: cstring, 
+                          clientData: Tcl_ClientData, 
+                          deleteProc: TTclNamespaceDeleteProc): pTcl_Namespace{.
+    cdecl, dynlib: dllName, importc.}
+  #v1.0
+proc Tcl_DeleteNamespace*(namespacePtr: pTcl_Namespace){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_FindNamespace*(interp: pTcl_Interp, name: cstring, 
+                        contextNsPtr: pTcl_Namespace, flags: int): pTcl_Namespace{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_Export*(interp: pTcl_Interp, namespacePtr: pTcl_Namespace, 
+                 pattern: cstring, resetListFirst: int): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_Import*(interp: pTcl_Interp, namespacePtr: pTcl_Namespace, 
+                 pattern: cstring, allowOverwrite: int): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GetCurrentNamespace*(interp: pTcl_Interp): pTcl_Namespace{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GetGlobalNamespace*(interp: pTcl_Interp): pTcl_Namespace{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_PushCallFrame*(interp: pTcl_Interp, callFramePtr: var Tcl_CallFrame, 
+                        namespacePtr: pTcl_Namespace, isProcCallFrame: int): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_PopCallFrame*(interp: pTcl_Interp){.cdecl, dynlib: dllName, importc.}
+proc Tcl_VarEval*(interp: pTcl_Interp): int{.cdecl, varargs, 
+    dynlib: dllName, importc.}
+  #* For TkConsole.c *
+proc Tcl_RecordAndEval*(interp: pTcl_Interp, cmd: cstring, flags: int): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GlobalEval*(interp: pTcl_Interp, command: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_DStringFree*(dsPtr: pTcl_DString){.cdecl, dynlib: dllName, importc.}
+proc Tcl_DStringAppend*(dsPtr: pTcl_DString, str: cstring, length: int): cstring{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_DStringAppendElement*(dsPtr: pTcl_DString, str: cstring): cstring{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_DStringInit*(dsPtr: pTcl_DString){.cdecl, dynlib: dllName, importc.}
+proc Tcl_AppendResult*(interp: pTcl_Interp){.cdecl, varargs, 
+    dynlib: dllName, importc.}
+  # actually a "C" var array
+proc Tcl_SetStdChannel*(channel: pTcl_Channel, typ: int){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_SetChannelOption*(interp: pTcl_Interp, chan: pTcl_Channel, 
+                           optionName: cstring, newValue: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GetChannelOption*(interp: pTcl_Interp, chan: pTcl_Channel, 
+                           optionName: cstring, dsPtr: pTcl_DString): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_CreateChannel*(typePtr: pTcl_ChannelType, chanName: cstring, 
+                        instanceData: Tcl_ClientData, mask: int): pTcl_Channel{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_RegisterChannel*(interp: pTcl_Interp, channel: pTcl_Channel){.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_UnregisterChannel*(interp: pTcl_Interp, channel: pTcl_Channel): int{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_CreateChannelHandler*(chan: pTcl_Channel, mask: int, 
+                               prc: TTclChannelProc, clientData: Tcl_ClientData){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GetChannel*(interp: pTcl_Interp, chanName: cstring, modePtr: pInteger): pTcl_Channel{.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GetStdChannel*(typ: int): pTcl_Channel{.cdecl, dynlib: dllName, 
+    importc.}
+proc Tcl_Gets*(chan: pTcl_Channel, dsPtr: pTcl_DString): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_Write*(chan: pTcl_Channel, s: cstring, slen: int): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_Flush*(chan: pTcl_Channel): int{.cdecl, dynlib: dllName, importc.}
+  #    TclWinLoadLibrary      = function(name: PChar): HMODULE; cdecl; external dllName;
+proc Tcl_CreateExitHandler*(prc: TTclClientDataProc, clientData: Tcl_ClientData){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_DeleteExitHandler*(prc: TTclClientDataProc, clientData: Tcl_ClientData){.
+    cdecl, dynlib: dllName, importc.}
+proc Tcl_GetStringFromObj*(pObj: pTcl_Obj, pLen: pInteger): cstring{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_CreateObjCommand*(interp: pTcl_Interp, name: cstring, 
+                           cmdProc: TTclObjCmdProc, clientData: Tcl_ClientData, 
+                           deleteProc: TTclCmdDeleteProc): pTcl_Command{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_NewStringObj*(bytes: cstring, length: int): pTcl_Obj{.cdecl, 
+    dynlib: dllName, importc.}
+  #    procedure TclFreeObj(pObj: pTcl_Obj); cdecl; external dllName;
+proc Tcl_EvalObj*(interp: pTcl_Interp, pObj: pTcl_Obj): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc Tcl_GlobalEvalObj*(interp: pTcl_Interp, pObj: pTcl_Obj): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc TclRegComp*(exp: cstring): pointer{.cdecl, dynlib: dllName, importc.}
+proc TclRegExec*(prog: pointer, str: cstring, start: cstring): int{.cdecl, 
+    dynlib: dllName, importc.}
+proc TclRegError*(msg: cstring){.cdecl, dynlib: dllName, importc.}
+proc TclGetRegError*(): cstring{.cdecl, dynlib: dllName, importc.}
+proc Tcl_RegExpRange*(prog: pointer, index: int, head: var cstring, 
+                      tail: var cstring){.cdecl, dynlib: dllName, importc.}
+
+proc Tcl_GetCommandTable*(interp: pTcl_Interp): pHashTable =
+  if interp != nil: 
+    result = cast[pHashTable](cast[int](interp) + sizeof(Tcl_Interp) + 
+      sizeof(pointer))
+
+proc Tcl_CreateHashEntry*(tablePtr: pTcl_HashTable, key: cstring, 
+                          newPtr: pInteger): pTcl_HashEntry =
+  result = cast[pHashTable](tablePtr).createProc(tablePtr, key, newPtr)
+                          
+proc Tcl_FindHashEntry*(tablePtr: pTcl_HashTable, 
+                        key: cstring): pTcl_HashEntry =
+  result = cast[pHashTable](tablePtr).findProc(tablePtr, key)
+
+proc Tcl_SetHashValue*(h: pTcl_HashEntry, clientData: Tcl_ClientData) =
+  h.clientData = clientData
+
+proc Tcl_GetHashValue*(h: pTcl_HashEntry): Tcl_ClientData =
+  result = h.clientData
+
+proc Tcl_IncrRefCount*(pObj: pTcl_Obj) =
+  inc(pObj.refCount)
+
+proc Tcl_DecrRefCount*(pObj: pTcl_Obj) =
+  dec(pObj.refCount)
+  if pObj.refCount <= 0: 
+    dealloc(pObj)
+
+proc Tcl_IsShared*(pObj: pTcl_Obj): bool = 
+  return pObj.refCount > 1
+
+proc Tcl_GetHashKey*(hashTbl: pTcl_HashTable, 
+                     hashEntry: pTcl_HashEntry): cstring = 
+  if hashTbl == nil or hashEntry == nil: 
+    result = nil
+  else: 
+    result = hashEntry.key
+  
diff --git a/lib/base/x11/cursorfont.nim b/lib/wrappers/x11/cursorfont.nim
index b262ad7c1..b262ad7c1 100644
--- a/lib/base/x11/cursorfont.nim
+++ b/lib/wrappers/x11/cursorfont.nim
diff --git a/lib/wrappers/x11/keysym.nim b/lib/wrappers/x11/keysym.nim
new file mode 100644
index 000000000..b1fe13b80
--- /dev/null
+++ b/lib/wrappers/x11/keysym.nim
@@ -0,0 +1,1925 @@
+#
+#Converted from X11/keysym.h and X11/keysymdef.h
+#
+#Capital letter consts renamed from XK_... to XKc_...
+# (since Pascal isn't case-sensitive)
+#
+#i.e.
+#C      Pascal
+#XK_a   XK_a
+#XK_A   XKc_A
+#
+
+#* default keysyms *
+
+const 
+  XK_VoidSymbol* = 0x00FFFFFF # void symbol 
+
+when defined(XK_MISCELLANY) or true: 
+  const
+    #*
+    # * TTY Functions, cleverly chosen to map to ascii, for convenience of
+    # * programming, but could have been arbitrary (at the cost of lookup
+    # * tables in client code.
+    # *
+    XK_BackSpace* = 0x0000FF08  # back space, back char 
+    XK_Tab* = 0x0000FF09
+    XK_Linefeed* = 0x0000FF0A   # Linefeed, LF 
+    XK_Clear* = 0x0000FF0B
+    XK_Return* = 0x0000FF0D     # Return, enter 
+    XK_Pause* = 0x0000FF13      # Pause, hold 
+    XK_Scroll_Lock* = 0x0000FF14
+    XK_Sys_Req* = 0x0000FF15
+    XK_Escape* = 0x0000FF1B
+    XK_Delete* = 0x0000FFFF     # Delete, rubout 
+                                # International & multi-key character composition 
+    XK_Multi_key* = 0x0000FF20  # Multi-key character compose 
+    XK_Codeinput* = 0x0000FF37
+    XK_SingleCandidate* = 0x0000FF3C
+    XK_MultipleCandidate* = 0x0000FF3D
+    XK_PreviousCandidate* = 0x0000FF3E # Japanese keyboard support 
+    XK_Kanji* = 0x0000FF21      # Kanji, Kanji convert 
+    XK_Muhenkan* = 0x0000FF22   # Cancel Conversion 
+    XK_Henkan_Mode* = 0x0000FF23 # Start/Stop Conversion 
+    XK_Henkan* = 0x0000FF23     # Alias for Henkan_Mode 
+    XK_Romaji* = 0x0000FF24     # to Romaji 
+    XK_Hiragana* = 0x0000FF25   # to Hiragana 
+    XK_Katakana* = 0x0000FF26   # to Katakana 
+    XK_Hiragana_Katakana* = 0x0000FF27 # Hiragana/Katakana toggle 
+    XK_Zenkaku* = 0x0000FF28    # to Zenkaku 
+    XK_Hankaku* = 0x0000FF29    # to Hankaku 
+    XK_Zenkaku_Hankaku* = 0x0000FF2A # Zenkaku/Hankaku toggle 
+    XK_Touroku* = 0x0000FF2B    # Add to Dictionary 
+    XK_Massyo* = 0x0000FF2C     # Delete from Dictionary 
+    XK_Kana_Lock* = 0x0000FF2D  # Kana Lock 
+    XK_Kana_Shift* = 0x0000FF2E # Kana Shift 
+    XK_Eisu_Shift* = 0x0000FF2F # Alphanumeric Shift 
+    XK_Eisu_toggle* = 0x0000FF30 # Alphanumeric toggle 
+    XK_Kanji_Bangou* = 0x0000FF37 # Codeinput 
+    XK_Zen_Koho* = 0x0000FF3D   # Multiple/All Candidate(s) 
+    XK_Mae_Koho* = 0x0000FF3E   # Previous Candidate 
+                                # = $FF31 thru = $FF3F are under XK_KOREAN 
+                                # Cursor control & motion 
+    XK_Home* = 0x0000FF50
+    XK_Left* = 0x0000FF51       # Move left, left arrow 
+    XK_Up* = 0x0000FF52         # Move up, up arrow 
+    XK_Right* = 0x0000FF53      # Move right, right arrow 
+    XK_Down* = 0x0000FF54       # Move down, down arrow 
+    XK_Prior* = 0x0000FF55      # Prior, previous 
+    XK_Page_Up* = 0x0000FF55
+    XK_Next* = 0x0000FF56       # Next 
+    XK_Page_Down* = 0x0000FF56
+    XK_End* = 0x0000FF57        # EOL 
+    XK_Begin* = 0x0000FF58      # BOL 
+                                # Misc Functions 
+    XK_Select* = 0x0000FF60     # Select, mark 
+    XK_Print* = 0x0000FF61
+    XK_Execute* = 0x0000FF62    # Execute, run, do 
+    XK_Insert* = 0x0000FF63     # Insert, insert here 
+    XK_Undo* = 0x0000FF65       # Undo, oops 
+    XK_Redo* = 0x0000FF66       # redo, again 
+    XK_Menu* = 0x0000FF67
+    XK_Find* = 0x0000FF68       # Find, search 
+    XK_Cancel* = 0x0000FF69     # Cancel, stop, abort, exit 
+    XK_Help* = 0x0000FF6A       # Help 
+    XK_Break* = 0x0000FF6B
+    XK_Mode_switch* = 0x0000FF7E # Character set switch 
+    XK_script_switch* = 0x0000FF7E # Alias for mode_switch 
+    XK_Num_Lock* = 0x0000FF7F   # Keypad Functions, keypad numbers cleverly chosen to map to ascii 
+    XK_KP_Space* = 0x0000FF80   # space 
+    XK_KP_Tab* = 0x0000FF89
+    XK_KP_Enter* = 0x0000FF8D   # enter 
+    XK_KP_F1* = 0x0000FF91      # PF1, KP_A, ... 
+    XK_KP_F2* = 0x0000FF92
+    XK_KP_F3* = 0x0000FF93
+    XK_KP_F4* = 0x0000FF94
+    XK_KP_Home* = 0x0000FF95
+    XK_KP_Left* = 0x0000FF96
+    XK_KP_Up* = 0x0000FF97
+    XK_KP_Right* = 0x0000FF98
+    XK_KP_Down* = 0x0000FF99
+    XK_KP_Prior* = 0x0000FF9A
+    XK_KP_Page_Up* = 0x0000FF9A
+    XK_KP_Next* = 0x0000FF9B
+    XK_KP_Page_Down* = 0x0000FF9B
+    XK_KP_End* = 0x0000FF9C
+    XK_KP_Begin* = 0x0000FF9D
+    XK_KP_Insert* = 0x0000FF9E
+    XK_KP_Delete* = 0x0000FF9F
+    XK_KP_Equal* = 0x0000FFBD   # equals 
+    XK_KP_Multiply* = 0x0000FFAA
+    XK_KP_Add* = 0x0000FFAB
+    XK_KP_Separator* = 0x0000FFAC # separator, often comma 
+    XK_KP_Subtract* = 0x0000FFAD
+    XK_KP_Decimal* = 0x0000FFAE
+    XK_KP_Divide* = 0x0000FFAF
+    XK_KP_0* = 0x0000FFB0
+    XK_KP_1* = 0x0000FFB1
+    XK_KP_2* = 0x0000FFB2
+    XK_KP_3* = 0x0000FFB3
+    XK_KP_4* = 0x0000FFB4
+    XK_KP_5* = 0x0000FFB5
+    XK_KP_6* = 0x0000FFB6
+    XK_KP_7* = 0x0000FFB7
+    XK_KP_8* = 0x0000FFB8
+    XK_KP_9* = 0x0000FFB9 #*
+                          # * Auxilliary Functions; note the duplicate definitions for left and right
+                          # * function keys;  Sun keyboards and a few other manufactures have such
+                          # * function key groups on the left and/or right sides of the keyboard.
+                          # * We've not found a keyboard with more than 35 function keys total.
+                          # *
+    XK_F1* = 0x0000FFBE
+    XK_F2* = 0x0000FFBF
+    XK_F3* = 0x0000FFC0
+    XK_F4* = 0x0000FFC1
+    XK_F5* = 0x0000FFC2
+    XK_F6* = 0x0000FFC3
+    XK_F7* = 0x0000FFC4
+    XK_F8* = 0x0000FFC5
+    XK_F9* = 0x0000FFC6
+    XK_F10* = 0x0000FFC7
+    XK_F11* = 0x0000FFC8
+    XK_L1* = 0x0000FFC8
+    XK_F12* = 0x0000FFC9
+    XK_L2* = 0x0000FFC9
+    XK_F13* = 0x0000FFCA
+    XK_L3* = 0x0000FFCA
+    XK_F14* = 0x0000FFCB
+    XK_L4* = 0x0000FFCB
+    XK_F15* = 0x0000FFCC
+    XK_L5* = 0x0000FFCC
+    XK_F16* = 0x0000FFCD
+    XK_L6* = 0x0000FFCD
+    XK_F17* = 0x0000FFCE
+    XK_L7* = 0x0000FFCE
+    XK_F18* = 0x0000FFCF
+    XK_L8* = 0x0000FFCF
+    XK_F19* = 0x0000FFD0
+    XK_L9* = 0x0000FFD0
+    XK_F20* = 0x0000FFD1
+    XK_L10* = 0x0000FFD1
+    XK_F21* = 0x0000FFD2
+    XK_R1* = 0x0000FFD2
+    XK_F22* = 0x0000FFD3
+    XK_R2* = 0x0000FFD3
+    XK_F23* = 0x0000FFD4
+    XK_R3* = 0x0000FFD4
+    XK_F24* = 0x0000FFD5
+    XK_R4* = 0x0000FFD5
+    XK_F25* = 0x0000FFD6
+    XK_R5* = 0x0000FFD6
+    XK_F26* = 0x0000FFD7
+    XK_R6* = 0x0000FFD7
+    XK_F27* = 0x0000FFD8
+    XK_R7* = 0x0000FFD8
+    XK_F28* = 0x0000FFD9
+    XK_R8* = 0x0000FFD9
+    XK_F29* = 0x0000FFDA
+    XK_R9* = 0x0000FFDA
+    XK_F30* = 0x0000FFDB
+    XK_R10* = 0x0000FFDB
+    XK_F31* = 0x0000FFDC
+    XK_R11* = 0x0000FFDC
+    XK_F32* = 0x0000FFDD
+    XK_R12* = 0x0000FFDD
+    XK_F33* = 0x0000FFDE
+    XK_R13* = 0x0000FFDE
+    XK_F34* = 0x0000FFDF
+    XK_R14* = 0x0000FFDF
+    XK_F35* = 0x0000FFE0
+    XK_R15* = 0x0000FFE0        # Modifiers 
+    XK_Shift_L* = 0x0000FFE1    # Left shift 
+    XK_Shift_R* = 0x0000FFE2    # Right shift 
+    XK_Control_L* = 0x0000FFE3  # Left control 
+    XK_Control_R* = 0x0000FFE4  # Right control 
+    XK_Caps_Lock* = 0x0000FFE5  # Caps lock 
+    XK_Shift_Lock* = 0x0000FFE6 # Shift lock 
+    XK_Meta_L* = 0x0000FFE7     # Left meta 
+    XK_Meta_R* = 0x0000FFE8     # Right meta 
+    XK_Alt_L* = 0x0000FFE9      # Left alt 
+    XK_Alt_R* = 0x0000FFEA      # Right alt 
+    XK_Super_L* = 0x0000FFEB    # Left super 
+    XK_Super_R* = 0x0000FFEC    # Right super 
+    XK_Hyper_L* = 0x0000FFED    # Left hyper 
+    XK_Hyper_R* = 0x0000FFEE    # Right hyper 
+# XK_MISCELLANY 
+#*
+# * ISO 9995 Function and Modifier Keys
+# * Byte 3 = = $FE
+# *
+
+when defined(XK_XKB_KEYS) or true: 
+  const
+    XK_ISO_Lock* = 0x0000FE01
+    XK_ISO_Level2_Latch* = 0x0000FE02
+    XK_ISO_Level3_Shift* = 0x0000FE03
+    XK_ISO_Level3_Latch* = 0x0000FE04
+    XK_ISO_Level3_Lock* = 0x0000FE05
+    XK_ISO_Group_Shift* = 0x0000FF7E # Alias for mode_switch 
+    XK_ISO_Group_Latch* = 0x0000FE06
+    XK_ISO_Group_Lock* = 0x0000FE07
+    XK_ISO_Next_Group* = 0x0000FE08
+    XK_ISO_Next_Group_Lock* = 0x0000FE09
+    XK_ISO_Prev_Group* = 0x0000FE0A
+    XK_ISO_Prev_Group_Lock* = 0x0000FE0B
+    XK_ISO_First_Group* = 0x0000FE0C
+    XK_ISO_First_Group_Lock* = 0x0000FE0D
+    XK_ISO_Last_Group* = 0x0000FE0E
+    XK_ISO_Last_Group_Lock* = 0x0000FE0F
+    XK_ISO_Left_Tab* = 0x0000FE20
+    XK_ISO_Move_Line_Up* = 0x0000FE21
+    XK_ISO_Move_Line_Down* = 0x0000FE22
+    XK_ISO_Partial_Line_Up* = 0x0000FE23
+    XK_ISO_Partial_Line_Down* = 0x0000FE24
+    XK_ISO_Partial_Space_Left* = 0x0000FE25
+    XK_ISO_Partial_Space_Right* = 0x0000FE26
+    XK_ISO_Set_Margin_Left* = 0x0000FE27
+    XK_ISO_Set_Margin_Right* = 0x0000FE28
+    XK_ISO_Release_Margin_Left* = 0x0000FE29
+    XK_ISO_Release_Margin_Right* = 0x0000FE2A
+    XK_ISO_Release_Both_Margins* = 0x0000FE2B
+    XK_ISO_Fast_Cursor_Left* = 0x0000FE2C
+    XK_ISO_Fast_Cursor_Right* = 0x0000FE2D
+    XK_ISO_Fast_Cursor_Up* = 0x0000FE2E
+    XK_ISO_Fast_Cursor_Down* = 0x0000FE2F
+    XK_ISO_Continuous_Underline* = 0x0000FE30
+    XK_ISO_Discontinuous_Underline* = 0x0000FE31
+    XK_ISO_Emphasize* = 0x0000FE32
+    XK_ISO_Center_Object* = 0x0000FE33
+    XK_ISO_Enter* = 0x0000FE34
+    XK_dead_grave* = 0x0000FE50
+    XK_dead_acute* = 0x0000FE51
+    XK_dead_circumflex* = 0x0000FE52
+    XK_dead_tilde* = 0x0000FE53
+    XK_dead_macron* = 0x0000FE54
+    XK_dead_breve* = 0x0000FE55
+    XK_dead_abovedot* = 0x0000FE56
+    XK_dead_diaeresis* = 0x0000FE57
+    XK_dead_abovering* = 0x0000FE58
+    XK_dead_doubleacute* = 0x0000FE59
+    XK_dead_caron* = 0x0000FE5A
+    XK_dead_cedilla* = 0x0000FE5B
+    XK_dead_ogonek* = 0x0000FE5C
+    XK_dead_iota* = 0x0000FE5D
+    XK_dead_voiced_sound* = 0x0000FE5E
+    XK_dead_semivoiced_sound* = 0x0000FE5F
+    XK_dead_belowdot* = 0x0000FE60
+    XK_dead_hook* = 0x0000FE61
+    XK_dead_horn* = 0x0000FE62
+    XK_First_Virtual_Screen* = 0x0000FED0
+    XK_Prev_Virtual_Screen* = 0x0000FED1
+    XK_Next_Virtual_Screen* = 0x0000FED2
+    XK_Last_Virtual_Screen* = 0x0000FED4
+    XK_Terminate_Server* = 0x0000FED5
+    XK_AccessX_Enable* = 0x0000FE70
+    XK_AccessX_Feedback_Enable* = 0x0000FE71
+    XK_RepeatKeys_Enable* = 0x0000FE72
+    XK_SlowKeys_Enable* = 0x0000FE73
+    XK_BounceKeys_Enable* = 0x0000FE74
+    XK_StickyKeys_Enable* = 0x0000FE75
+    XK_MouseKeys_Enable* = 0x0000FE76
+    XK_MouseKeys_Accel_Enable* = 0x0000FE77
+    XK_Overlay1_Enable* = 0x0000FE78
+    XK_Overlay2_Enable* = 0x0000FE79
+    XK_AudibleBell_Enable* = 0x0000FE7A
+    XK_Pointer_Left* = 0x0000FEE0
+    XK_Pointer_Right* = 0x0000FEE1
+    XK_Pointer_Up* = 0x0000FEE2
+    XK_Pointer_Down* = 0x0000FEE3
+    XK_Pointer_UpLeft* = 0x0000FEE4
+    XK_Pointer_UpRight* = 0x0000FEE5
+    XK_Pointer_DownLeft* = 0x0000FEE6
+    XK_Pointer_DownRight* = 0x0000FEE7
+    XK_Pointer_Button_Dflt* = 0x0000FEE8
+    XK_Pointer_Button1* = 0x0000FEE9
+    XK_Pointer_Button2* = 0x0000FEEA
+    XK_Pointer_Button3* = 0x0000FEEB
+    XK_Pointer_Button4* = 0x0000FEEC
+    XK_Pointer_Button5* = 0x0000FEED
+    XK_Pointer_DblClick_Dflt* = 0x0000FEEE
+    XK_Pointer_DblClick1* = 0x0000FEEF
+    XK_Pointer_DblClick2* = 0x0000FEF0
+    XK_Pointer_DblClick3* = 0x0000FEF1
+    XK_Pointer_DblClick4* = 0x0000FEF2
+    XK_Pointer_DblClick5* = 0x0000FEF3
+    XK_Pointer_Drag_Dflt* = 0x0000FEF4
+    XK_Pointer_Drag1* = 0x0000FEF5
+    XK_Pointer_Drag2* = 0x0000FEF6
+    XK_Pointer_Drag3* = 0x0000FEF7
+    XK_Pointer_Drag4* = 0x0000FEF8
+    XK_Pointer_Drag5* = 0x0000FEFD
+    XK_Pointer_EnableKeys* = 0x0000FEF9
+    XK_Pointer_Accelerate* = 0x0000FEFA
+    XK_Pointer_DfltBtnNext* = 0x0000FEFB
+    XK_Pointer_DfltBtnPrev* = 0x0000FEFC
+  #*
+  # * 3270 Terminal Keys
+  # * Byte 3 = = $FD
+  # *
+
+when defined(XK_3270) or true: 
+  const
+    XK_3270_Duplicate* = 0x0000FD01
+    XK_3270_FieldMark* = 0x0000FD02
+    XK_3270_Right2* = 0x0000FD03
+    XK_3270_Left2* = 0x0000FD04
+    XK_3270_BackTab* = 0x0000FD05
+    XK_3270_EraseEOF* = 0x0000FD06
+    XK_3270_EraseInput* = 0x0000FD07
+    XK_3270_Reset* = 0x0000FD08
+    XK_3270_Quit* = 0x0000FD09
+    XK_3270_PA1* = 0x0000FD0A
+    XK_3270_PA2* = 0x0000FD0B
+    XK_3270_PA3* = 0x0000FD0C
+    XK_3270_Test* = 0x0000FD0D
+    XK_3270_Attn* = 0x0000FD0E
+    XK_3270_CursorBlink* = 0x0000FD0F
+    XK_3270_AltCursor* = 0x0000FD10
+    XK_3270_KeyClick* = 0x0000FD11
+    XK_3270_Jump* = 0x0000FD12
+    XK_3270_Ident* = 0x0000FD13
+    XK_3270_Rule* = 0x0000FD14
+    XK_3270_Copy* = 0x0000FD15
+    XK_3270_Play* = 0x0000FD16
+    XK_3270_Setup* = 0x0000FD17
+    XK_3270_Record* = 0x0000FD18
+    XK_3270_ChangeScreen* = 0x0000FD19
+    XK_3270_DeleteWord* = 0x0000FD1A
+    XK_3270_ExSelect* = 0x0000FD1B
+    XK_3270_CursorSelect* = 0x0000FD1C
+    XK_3270_PrintScreen* = 0x0000FD1D
+    XK_3270_Enter* = 0x0000FD1E
+#*
+# *  Latin 1
+# *  Byte 3 = 0
+# *
+
+when defined(XK_LATIN1) or true: 
+  const
+    XK_space* = 0x00000020
+    XK_exclam* = 0x00000021
+    XK_quotedbl* = 0x00000022
+    XK_numbersign* = 0x00000023
+    XK_dollar* = 0x00000024
+    XK_percent* = 0x00000025
+    XK_ampersand* = 0x00000026
+    XK_apostrophe* = 0x00000027
+    XK_quoteright* = 0x00000027 # deprecated 
+    XK_parenleft* = 0x00000028
+    XK_parenright* = 0x00000029
+    XK_asterisk* = 0x0000002A
+    XK_plus* = 0x0000002B
+    XK_comma* = 0x0000002C
+    XK_minus* = 0x0000002D
+    XK_period* = 0x0000002E
+    XK_slash* = 0x0000002F
+    XK_0* = 0x00000030
+    XK_1* = 0x00000031
+    XK_2* = 0x00000032
+    XK_3* = 0x00000033
+    XK_4* = 0x00000034
+    XK_5* = 0x00000035
+    XK_6* = 0x00000036
+    XK_7* = 0x00000037
+    XK_8* = 0x00000038
+    XK_9* = 0x00000039
+    XK_colon* = 0x0000003A
+    XK_semicolon* = 0x0000003B
+    XK_less* = 0x0000003C
+    XK_equal* = 0x0000003D
+    XK_greater* = 0x0000003E
+    XK_question* = 0x0000003F
+    XK_at* = 0x00000040
+    XKc_A* = 0x00000041
+    XKc_B* = 0x00000042
+    XKc_C* = 0x00000043
+    XKc_D* = 0x00000044
+    XKc_E* = 0x00000045
+    XKc_F* = 0x00000046
+    XKc_G* = 0x00000047
+    XKc_H* = 0x00000048
+    XKc_I* = 0x00000049
+    XKc_J* = 0x0000004A
+    XKc_K* = 0x0000004B
+    XKc_L* = 0x0000004C
+    XKc_M* = 0x0000004D
+    XKc_N* = 0x0000004E
+    XKc_O* = 0x0000004F
+    XKc_P* = 0x00000050
+    XKc_Q* = 0x00000051
+    XKc_R* = 0x00000052
+    XKc_S* = 0x00000053
+    XKc_T* = 0x00000054
+    XKc_U* = 0x00000055
+    XKc_V* = 0x00000056
+    XKc_W* = 0x00000057
+    XKc_X* = 0x00000058
+    XKc_Y* = 0x00000059
+    XKc_Z* = 0x0000005A
+    XK_bracketleft* = 0x0000005B
+    XK_backslash* = 0x0000005C
+    XK_bracketright* = 0x0000005D
+    XK_asciicircum* = 0x0000005E
+    XK_underscore* = 0x0000005F
+    XK_grave* = 0x00000060
+    XK_quoteleft* = 0x00000060  # deprecated 
+    XK_a* = 0x00000061
+    XK_b* = 0x00000062
+    XK_c* = 0x00000063
+    XK_d* = 0x00000064
+    XK_e* = 0x00000065
+    XK_f* = 0x00000066
+    XK_g* = 0x00000067
+    XK_h* = 0x00000068
+    XK_i* = 0x00000069
+    XK_j* = 0x0000006A
+    XK_k* = 0x0000006B
+    XK_l* = 0x0000006C
+    XK_m* = 0x0000006D
+    XK_n* = 0x0000006E
+    XK_o* = 0x0000006F
+    XK_p* = 0x00000070
+    XK_q* = 0x00000071
+    XK_r* = 0x00000072
+    XK_s* = 0x00000073
+    XK_t* = 0x00000074
+    XK_u* = 0x00000075
+    XK_v* = 0x00000076
+    XK_w* = 0x00000077
+    XK_x* = 0x00000078
+    XK_y* = 0x00000079
+    XK_z* = 0x0000007A
+    XK_braceleft* = 0x0000007B
+    XK_bar* = 0x0000007C
+    XK_braceright* = 0x0000007D
+    XK_asciitilde* = 0x0000007E
+    XK_nobreakspace* = 0x000000A0
+    XK_exclamdown* = 0x000000A1
+    XK_cent* = 0x000000A2
+    XK_sterling* = 0x000000A3
+    XK_currency* = 0x000000A4
+    XK_yen* = 0x000000A5
+    XK_brokenbar* = 0x000000A6
+    XK_section* = 0x000000A7
+    XK_diaeresis* = 0x000000A8
+    XK_copyright* = 0x000000A9
+    XK_ordfeminine* = 0x000000AA
+    XK_guillemotleft* = 0x000000AB # left angle quotation mark 
+    XK_notsign* = 0x000000AC
+    XK_hyphen* = 0x000000AD
+    XK_registered* = 0x000000AE
+    XK_macron* = 0x000000AF
+    XK_degree* = 0x000000B0
+    XK_plusminus* = 0x000000B1
+    XK_twosuperior* = 0x000000B2
+    XK_threesuperior* = 0x000000B3
+    XK_acute* = 0x000000B4
+    XK_mu* = 0x000000B5
+    XK_paragraph* = 0x000000B6
+    XK_periodcentered* = 0x000000B7
+    XK_cedilla* = 0x000000B8
+    XK_onesuperior* = 0x000000B9
+    XK_masculine* = 0x000000BA
+    XK_guillemotright* = 0x000000BB # right angle quotation mark 
+    XK_onequarter* = 0x000000BC
+    XK_onehalf* = 0x000000BD
+    XK_threequarters* = 0x000000BE
+    XK_questiondown* = 0x000000BF
+    XKc_Agrave* = 0x000000C0
+    XKc_Aacute* = 0x000000C1
+    XKc_Acircumflex* = 0x000000C2
+    XKc_Atilde* = 0x000000C3
+    XKc_Adiaeresis* = 0x000000C4
+    XKc_Aring* = 0x000000C5
+    XKc_AE* = 0x000000C6
+    XKc_Ccedilla* = 0x000000C7
+    XKc_Egrave* = 0x000000C8
+    XKc_Eacute* = 0x000000C9
+    XKc_Ecircumflex* = 0x000000CA
+    XKc_Ediaeresis* = 0x000000CB
+    XKc_Igrave* = 0x000000CC
+    XKc_Iacute* = 0x000000CD
+    XKc_Icircumflex* = 0x000000CE
+    XKc_Idiaeresis* = 0x000000CF
+    XKc_ETH* = 0x000000D0
+    XKc_Ntilde* = 0x000000D1
+    XKc_Ograve* = 0x000000D2
+    XKc_Oacute* = 0x000000D3
+    XKc_Ocircumflex* = 0x000000D4
+    XKc_Otilde* = 0x000000D5
+    XKc_Odiaeresis* = 0x000000D6
+    XK_multiply* = 0x000000D7
+    XKc_Ooblique* = 0x000000D8
+    XKc_Oslash* = XKc_Ooblique
+    XKc_Ugrave* = 0x000000D9
+    XKc_Uacute* = 0x000000DA
+    XKc_Ucircumflex* = 0x000000DB
+    XKc_Udiaeresis* = 0x000000DC
+    XKc_Yacute* = 0x000000DD
+    XKc_THORN* = 0x000000DE
+    XK_ssharp* = 0x000000DF
+    XK_agrave* = 0x000000E0
+    XK_aacute* = 0x000000E1
+    XK_acircumflex* = 0x000000E2
+    XK_atilde* = 0x000000E3
+    XK_adiaeresis* = 0x000000E4
+    XK_aring* = 0x000000E5
+    XK_ae* = 0x000000E6
+    XK_ccedilla* = 0x000000E7
+    XK_egrave* = 0x000000E8
+    XK_eacute* = 0x000000E9
+    XK_ecircumflex* = 0x000000EA
+    XK_ediaeresis* = 0x000000EB
+    XK_igrave* = 0x000000EC
+    XK_iacute* = 0x000000ED
+    XK_icircumflex* = 0x000000EE
+    XK_idiaeresis* = 0x000000EF
+    XK_eth* = 0x000000F0
+    XK_ntilde* = 0x000000F1
+    XK_ograve* = 0x000000F2
+    XK_oacute* = 0x000000F3
+    XK_ocircumflex* = 0x000000F4
+    XK_otilde* = 0x000000F5
+    XK_odiaeresis* = 0x000000F6
+    XK_division* = 0x000000F7
+    XK_oslash* = 0x000000F8
+    XK_ooblique* = XK_oslash
+    XK_ugrave* = 0x000000F9
+    XK_uacute* = 0x000000FA
+    XK_ucircumflex* = 0x000000FB
+    XK_udiaeresis* = 0x000000FC
+    XK_yacute* = 0x000000FD
+    XK_thorn* = 0x000000FE
+    XK_ydiaeresis* = 0x000000FF
+# XK_LATIN1 
+#*
+# *   Latin 2
+# *   Byte 3 = 1
+# *
+
+when defined(XK_LATIN2) or true: 
+  const
+    XKc_Aogonek* = 0x000001A1
+    XK_breve* = 0x000001A2
+    XKc_Lstroke* = 0x000001A3
+    XKc_Lcaron* = 0x000001A5
+    XKc_Sacute* = 0x000001A6
+    XKc_Scaron* = 0x000001A9
+    XKc_Scedilla* = 0x000001AA
+    XKc_Tcaron* = 0x000001AB
+    XKc_Zacute* = 0x000001AC
+    XKc_Zcaron* = 0x000001AE
+    XKc_Zabovedot* = 0x000001AF
+    XK_aogonek* = 0x000001B1
+    XK_ogonek* = 0x000001B2
+    XK_lstroke* = 0x000001B3
+    XK_lcaron* = 0x000001B5
+    XK_sacute* = 0x000001B6
+    XK_caron* = 0x000001B7
+    XK_scaron* = 0x000001B9
+    XK_scedilla* = 0x000001BA
+    XK_tcaron* = 0x000001BB
+    XK_zacute* = 0x000001BC
+    XK_doubleacute* = 0x000001BD
+    XK_zcaron* = 0x000001BE
+    XK_zabovedot* = 0x000001BF
+    XKc_Racute* = 0x000001C0
+    XKc_Abreve* = 0x000001C3
+    XKc_Lacute* = 0x000001C5
+    XKc_Cacute* = 0x000001C6
+    XKc_Ccaron* = 0x000001C8
+    XKc_Eogonek* = 0x000001CA
+    XKc_Ecaron* = 0x000001CC
+    XKc_Dcaron* = 0x000001CF
+    XKc_Dstroke* = 0x000001D0
+    XKc_Nacute* = 0x000001D1
+    XKc_Ncaron* = 0x000001D2
+    XKc_Odoubleacute* = 0x000001D5
+    XKc_Rcaron* = 0x000001D8
+    XKc_Uring* = 0x000001D9
+    XKc_Udoubleacute* = 0x000001DB
+    XKc_Tcedilla* = 0x000001DE
+    XK_racute* = 0x000001E0
+    XK_abreve* = 0x000001E3
+    XK_lacute* = 0x000001E5
+    XK_cacute* = 0x000001E6
+    XK_ccaron* = 0x000001E8
+    XK_eogonek* = 0x000001EA
+    XK_ecaron* = 0x000001EC
+    XK_dcaron* = 0x000001EF
+    XK_dstroke* = 0x000001F0
+    XK_nacute* = 0x000001F1
+    XK_ncaron* = 0x000001F2
+    XK_odoubleacute* = 0x000001F5
+    XK_udoubleacute* = 0x000001FB
+    XK_rcaron* = 0x000001F8
+    XK_uring* = 0x000001F9
+    XK_tcedilla* = 0x000001FE
+    XK_abovedot* = 0x000001FF
+# XK_LATIN2 
+#*
+# *   Latin 3
+# *   Byte 3 = 2
+# *
+
+when defined(XK_LATIN3) or true: 
+  const
+    XKc_Hstroke* = 0x000002A1
+    XKc_Hcircumflex* = 0x000002A6
+    XKc_Iabovedot* = 0x000002A9
+    XKc_Gbreve* = 0x000002AB
+    XKc_Jcircumflex* = 0x000002AC
+    XK_hstroke* = 0x000002B1
+    XK_hcircumflex* = 0x000002B6
+    XK_idotless* = 0x000002B9
+    XK_gbreve* = 0x000002BB
+    XK_jcircumflex* = 0x000002BC
+    XKc_Cabovedot* = 0x000002C5
+    XKc_Ccircumflex* = 0x000002C6
+    XKc_Gabovedot* = 0x000002D5
+    XKc_Gcircumflex* = 0x000002D8
+    XKc_Ubreve* = 0x000002DD
+    XKc_Scircumflex* = 0x000002DE
+    XK_cabovedot* = 0x000002E5
+    XK_ccircumflex* = 0x000002E6
+    XK_gabovedot* = 0x000002F5
+    XK_gcircumflex* = 0x000002F8
+    XK_ubreve* = 0x000002FD
+    XK_scircumflex* = 0x000002FE
+# XK_LATIN3 
+#*
+# *   Latin 4
+# *   Byte 3 = 3
+# *
+
+when defined(XK_LATIN4) or true: 
+  const
+    XK_kra* = 0x000003A2
+    XK_kappa* = 0x000003A2      # deprecated 
+    XKc_Rcedilla* = 0x000003A3
+    XKc_Itilde* = 0x000003A5
+    XKc_Lcedilla* = 0x000003A6
+    XKc_Emacron* = 0x000003AA
+    XKc_Gcedilla* = 0x000003AB
+    XKc_Tslash* = 0x000003AC
+    XK_rcedilla* = 0x000003B3
+    XK_itilde* = 0x000003B5
+    XK_lcedilla* = 0x000003B6
+    XK_emacron* = 0x000003BA
+    XK_gcedilla* = 0x000003BB
+    XK_tslash* = 0x000003BC
+    XKc_ENG* = 0x000003BD
+    XK_eng* = 0x000003BF
+    XKc_Amacron* = 0x000003C0
+    XKc_Iogonek* = 0x000003C7
+    XKc_Eabovedot* = 0x000003CC
+    XKc_Imacron* = 0x000003CF
+    XKc_Ncedilla* = 0x000003D1
+    XKc_Omacron* = 0x000003D2
+    XKc_Kcedilla* = 0x000003D3
+    XKc_Uogonek* = 0x000003D9
+    XKc_Utilde* = 0x000003DD
+    XKc_Umacron* = 0x000003DE
+    XK_amacron* = 0x000003E0
+    XK_iogonek* = 0x000003E7
+    XK_eabovedot* = 0x000003EC
+    XK_imacron* = 0x000003EF
+    XK_ncedilla* = 0x000003F1
+    XK_omacron* = 0x000003F2
+    XK_kcedilla* = 0x000003F3
+    XK_uogonek* = 0x000003F9
+    XK_utilde* = 0x000003FD
+    XK_umacron* = 0x000003FE
+# XK_LATIN4 
+#*
+# * Latin-8
+# * Byte 3 = 18
+# *
+
+when defined(XK_LATIN8) or true: 
+  const
+    XKc_Babovedot* = 0x000012A1
+    XK_babovedot* = 0x000012A2
+    XKc_Dabovedot* = 0x000012A6
+    XKc_Wgrave* = 0x000012A8
+    XKc_Wacute* = 0x000012AA
+    XK_dabovedot* = 0x000012AB
+    XKc_Ygrave* = 0x000012AC
+    XKc_Fabovedot* = 0x000012B0
+    XK_fabovedot* = 0x000012B1
+    XKc_Mabovedot* = 0x000012B4
+    XK_mabovedot* = 0x000012B5
+    XKc_Pabovedot* = 0x000012B7
+    XK_wgrave* = 0x000012B8
+    XK_pabovedot* = 0x000012B9
+    XK_wacute* = 0x000012BA
+    XKc_Sabovedot* = 0x000012BB
+    XK_ygrave* = 0x000012BC
+    XKc_Wdiaeresis* = 0x000012BD
+    XK_wdiaeresis* = 0x000012BE
+    XK_sabovedot* = 0x000012BF
+    XKc_Wcircumflex* = 0x000012D0
+    XKc_Tabovedot* = 0x000012D7
+    XKc_Ycircumflex* = 0x000012DE
+    XK_wcircumflex* = 0x000012F0
+    XK_tabovedot* = 0x000012F7
+    XK_ycircumflex* = 0x000012FE
+# XK_LATIN8 
+#*
+# * Latin-9 (a.k.a. Latin-0)
+# * Byte 3 = 19
+# *
+
+when defined(XK_LATIN9) or true: 
+  const
+    XKc_OE* = 0x000013BC
+    XK_oe* = 0x000013BD
+    XKc_Ydiaeresis* = 0x000013BE
+# XK_LATIN9 
+#*
+# * Katakana
+# * Byte 3 = 4
+# *
+
+when defined(XK_KATAKANA) or true: 
+  const
+    XK_overline* = 0x0000047E
+    XK_kana_fullstop* = 0x000004A1
+    XK_kana_openingbracket* = 0x000004A2
+    XK_kana_closingbracket* = 0x000004A3
+    XK_kana_comma* = 0x000004A4
+    XK_kana_conjunctive* = 0x000004A5
+    XK_kana_middledot* = 0x000004A5 # deprecated 
+    XKc_kana_WO* = 0x000004A6
+    XK_kana_a* = 0x000004A7
+    XK_kana_i* = 0x000004A8
+    XK_kana_u* = 0x000004A9
+    XK_kana_e* = 0x000004AA
+    XK_kana_o* = 0x000004AB
+    XK_kana_ya* = 0x000004AC
+    XK_kana_yu* = 0x000004AD
+    XK_kana_yo* = 0x000004AE
+    XK_kana_tsu* = 0x000004AF
+    XK_kana_tu* = 0x000004AF    # deprecated 
+    XK_prolongedsound* = 0x000004B0
+    XKc_kana_A* = 0x000004B1
+    XKc_kana_I* = 0x000004B2
+    XKc_kana_U* = 0x000004B3
+    XKc_kana_E* = 0x000004B4
+    XKc_kana_O* = 0x000004B5
+    XKc_kana_KA* = 0x000004B6
+    XKc_kana_KI* = 0x000004B7
+    XKc_kana_KU* = 0x000004B8
+    XKc_kana_KE* = 0x000004B9
+    XKc_kana_KO* = 0x000004BA
+    XKc_kana_SA* = 0x000004BB
+    XKc_kana_SHI* = 0x000004BC
+    XKc_kana_SU* = 0x000004BD
+    XKc_kana_SE* = 0x000004BE
+    XKc_kana_SO* = 0x000004BF
+    XKc_kana_TA* = 0x000004C0
+    XKc_kana_CHI* = 0x000004C1
+    XKc_kana_TI* = 0x000004C1   # deprecated 
+    XKc_kana_TSU* = 0x000004C2
+    XKc_kana_TU* = 0x000004C2   # deprecated 
+    XKc_kana_TE* = 0x000004C3
+    XKc_kana_TO* = 0x000004C4
+    XKc_kana_NA* = 0x000004C5
+    XKc_kana_NI* = 0x000004C6
+    XKc_kana_NU* = 0x000004C7
+    XKc_kana_NE* = 0x000004C8
+    XKc_kana_NO* = 0x000004C9
+    XKc_kana_HA* = 0x000004CA
+    XKc_kana_HI* = 0x000004CB
+    XKc_kana_FU* = 0x000004CC
+    XKc_kana_HU* = 0x000004CC   # deprecated 
+    XKc_kana_HE* = 0x000004CD
+    XKc_kana_HO* = 0x000004CE
+    XKc_kana_MA* = 0x000004CF
+    XKc_kana_MI* = 0x000004D0
+    XKc_kana_MU* = 0x000004D1
+    XKc_kana_ME* = 0x000004D2
+    XKc_kana_MO* = 0x000004D3
+    XKc_kana_YA* = 0x000004D4
+    XKc_kana_YU* = 0x000004D5
+    XKc_kana_YO* = 0x000004D6
+    XKc_kana_RA* = 0x000004D7
+    XKc_kana_RI* = 0x000004D8
+    XKc_kana_RU* = 0x000004D9
+    XKc_kana_RE* = 0x000004DA
+    XKc_kana_RO* = 0x000004DB
+    XKc_kana_WA* = 0x000004DC
+    XKc_kana_N* = 0x000004DD
+    XK_voicedsound* = 0x000004DE
+    XK_semivoicedsound* = 0x000004DF
+    XK_kana_switch* = 0x0000FF7E # Alias for mode_switch 
+# XK_KATAKANA 
+#*
+# *  Arabic
+# *  Byte 3 = 5
+# *
+
+when defined(XK_ARABIC) or true: 
+  const
+    XK_Farsi_0* = 0x00000590
+    XK_Farsi_1* = 0x00000591
+    XK_Farsi_2* = 0x00000592
+    XK_Farsi_3* = 0x00000593
+    XK_Farsi_4* = 0x00000594
+    XK_Farsi_5* = 0x00000595
+    XK_Farsi_6* = 0x00000596
+    XK_Farsi_7* = 0x00000597
+    XK_Farsi_8* = 0x00000598
+    XK_Farsi_9* = 0x00000599
+    XK_Arabic_percent* = 0x000005A5
+    XK_Arabic_superscript_alef* = 0x000005A6
+    XK_Arabic_tteh* = 0x000005A7
+    XK_Arabic_peh* = 0x000005A8
+    XK_Arabic_tcheh* = 0x000005A9
+    XK_Arabic_ddal* = 0x000005AA
+    XK_Arabic_rreh* = 0x000005AB
+    XK_Arabic_comma* = 0x000005AC
+    XK_Arabic_fullstop* = 0x000005AE
+    XK_Arabic_0* = 0x000005B0
+    XK_Arabic_1* = 0x000005B1
+    XK_Arabic_2* = 0x000005B2
+    XK_Arabic_3* = 0x000005B3
+    XK_Arabic_4* = 0x000005B4
+    XK_Arabic_5* = 0x000005B5
+    XK_Arabic_6* = 0x000005B6
+    XK_Arabic_7* = 0x000005B7
+    XK_Arabic_8* = 0x000005B8
+    XK_Arabic_9* = 0x000005B9
+    XK_Arabic_semicolon* = 0x000005BB
+    XK_Arabic_question_mark* = 0x000005BF
+    XK_Arabic_hamza* = 0x000005C1
+    XK_Arabic_maddaonalef* = 0x000005C2
+    XK_Arabic_hamzaonalef* = 0x000005C3
+    XK_Arabic_hamzaonwaw* = 0x000005C4
+    XK_Arabic_hamzaunderalef* = 0x000005C5
+    XK_Arabic_hamzaonyeh* = 0x000005C6
+    XK_Arabic_alef* = 0x000005C7
+    XK_Arabic_beh* = 0x000005C8
+    XK_Arabic_tehmarbuta* = 0x000005C9
+    XK_Arabic_teh* = 0x000005CA
+    XK_Arabic_theh* = 0x000005CB
+    XK_Arabic_jeem* = 0x000005CC
+    XK_Arabic_hah* = 0x000005CD
+    XK_Arabic_khah* = 0x000005CE
+    XK_Arabic_dal* = 0x000005CF
+    XK_Arabic_thal* = 0x000005D0
+    XK_Arabic_ra* = 0x000005D1
+    XK_Arabic_zain* = 0x000005D2
+    XK_Arabic_seen* = 0x000005D3
+    XK_Arabic_sheen* = 0x000005D4
+    XK_Arabic_sad* = 0x000005D5
+    XK_Arabic_dad* = 0x000005D6
+    XK_Arabic_tah* = 0x000005D7
+    XK_Arabic_zah* = 0x000005D8
+    XK_Arabic_ain* = 0x000005D9
+    XK_Arabic_ghain* = 0x000005DA
+    XK_Arabic_tatweel* = 0x000005E0
+    XK_Arabic_feh* = 0x000005E1
+    XK_Arabic_qaf* = 0x000005E2
+    XK_Arabic_kaf* = 0x000005E3
+    XK_Arabic_lam* = 0x000005E4
+    XK_Arabic_meem* = 0x000005E5
+    XK_Arabic_noon* = 0x000005E6
+    XK_Arabic_ha* = 0x000005E7
+    XK_Arabic_heh* = 0x000005E7 # deprecated 
+    XK_Arabic_waw* = 0x000005E8
+    XK_Arabic_alefmaksura* = 0x000005E9
+    XK_Arabic_yeh* = 0x000005EA
+    XK_Arabic_fathatan* = 0x000005EB
+    XK_Arabic_dammatan* = 0x000005EC
+    XK_Arabic_kasratan* = 0x000005ED
+    XK_Arabic_fatha* = 0x000005EE
+    XK_Arabic_damma* = 0x000005EF
+    XK_Arabic_kasra* = 0x000005F0
+    XK_Arabic_shadda* = 0x000005F1
+    XK_Arabic_sukun* = 0x000005F2
+    XK_Arabic_madda_above* = 0x000005F3
+    XK_Arabic_hamza_above* = 0x000005F4
+    XK_Arabic_hamza_below* = 0x000005F5
+    XK_Arabic_jeh* = 0x000005F6
+    XK_Arabic_veh* = 0x000005F7
+    XK_Arabic_keheh* = 0x000005F8
+    XK_Arabic_gaf* = 0x000005F9
+    XK_Arabic_noon_ghunna* = 0x000005FA
+    XK_Arabic_heh_doachashmee* = 0x000005FB
+    XK_Farsi_yeh* = 0x000005FC
+    XK_Arabic_farsi_yeh* = XK_Farsi_yeh
+    XK_Arabic_yeh_baree* = 0x000005FD
+    XK_Arabic_heh_goal* = 0x000005FE
+    XK_Arabic_switch* = 0x0000FF7E # Alias for mode_switch 
+# XK_ARABIC 
+#*
+# * Cyrillic
+# * Byte 3 = 6
+# *
+
+when defined(XK_CYRILLIC) or true: 
+  const
+    XKc_Cyrillic_GHE_bar* = 0x00000680
+    XK_Cyrillic_ghe_bar* = 0x00000690
+    XKc_Cyrillic_ZHE_descender* = 0x00000681
+    XK_Cyrillic_zhe_descender* = 0x00000691
+    XKc_Cyrillic_KA_descender* = 0x00000682
+    XK_Cyrillic_ka_descender* = 0x00000692
+    XKc_Cyrillic_KA_vertstroke* = 0x00000683
+    XK_Cyrillic_ka_vertstroke* = 0x00000693
+    XKc_Cyrillic_EN_descender* = 0x00000684
+    XK_Cyrillic_en_descender* = 0x00000694
+    XKc_Cyrillic_U_straight* = 0x00000685
+    XK_Cyrillic_u_straight* = 0x00000695
+    XKc_Cyrillic_U_straight_bar* = 0x00000686
+    XK_Cyrillic_u_straight_bar* = 0x00000696
+    XKc_Cyrillic_HA_descender* = 0x00000687
+    XK_Cyrillic_ha_descender* = 0x00000697
+    XKc_Cyrillic_CHE_descender* = 0x00000688
+    XK_Cyrillic_che_descender* = 0x00000698
+    XKc_Cyrillic_CHE_vertstroke* = 0x00000689
+    XK_Cyrillic_che_vertstroke* = 0x00000699
+    XKc_Cyrillic_SHHA* = 0x0000068A
+    XK_Cyrillic_shha* = 0x0000069A
+    XKc_Cyrillic_SCHWA* = 0x0000068C
+    XK_Cyrillic_schwa* = 0x0000069C
+    XKc_Cyrillic_I_macron* = 0x0000068D
+    XK_Cyrillic_i_macron* = 0x0000069D
+    XKc_Cyrillic_O_bar* = 0x0000068E
+    XK_Cyrillic_o_bar* = 0x0000069E
+    XKc_Cyrillic_U_macron* = 0x0000068F
+    XK_Cyrillic_u_macron* = 0x0000069F
+    XK_Serbian_dje* = 0x000006A1
+    XK_Macedonia_gje* = 0x000006A2
+    XK_Cyrillic_io* = 0x000006A3
+    XK_Ukrainian_ie* = 0x000006A4
+    XK_Ukranian_je* = 0x000006A4 # deprecated 
+    XK_Macedonia_dse* = 0x000006A5
+    XK_Ukrainian_i* = 0x000006A6
+    XK_Ukranian_i* = 0x000006A6 # deprecated 
+    XK_Ukrainian_yi* = 0x000006A7
+    XK_Ukranian_yi* = 0x000006A7 # deprecated 
+    XK_Cyrillic_je* = 0x000006A8
+    XK_Serbian_je* = 0x000006A8 # deprecated 
+    XK_Cyrillic_lje* = 0x000006A9
+    XK_Serbian_lje* = 0x000006A9 # deprecated 
+    XK_Cyrillic_nje* = 0x000006AA
+    XK_Serbian_nje* = 0x000006AA # deprecated 
+    XK_Serbian_tshe* = 0x000006AB
+    XK_Macedonia_kje* = 0x000006AC
+    XK_Ukrainian_ghe_with_upturn* = 0x000006AD
+    XK_Byelorussian_shortu* = 0x000006AE
+    XK_Cyrillic_dzhe* = 0x000006AF
+    XK_Serbian_dze* = 0x000006AF # deprecated 
+    XK_numerosign* = 0x000006B0
+    XKc_Serbian_DJE* = 0x000006B1
+    XKc_Macedonia_GJE* = 0x000006B2
+    XKc_Cyrillic_IO* = 0x000006B3
+    XKc_Ukrainian_IE* = 0x000006B4
+    XKc_Ukranian_JE* = 0x000006B4 # deprecated 
+    XKc_Macedonia_DSE* = 0x000006B5
+    XKc_Ukrainian_I* = 0x000006B6
+    XKc_Ukranian_I* = 0x000006B6 # deprecated 
+    XKc_Ukrainian_YI* = 0x000006B7
+    XKc_Ukranian_YI* = 0x000006B7 # deprecated 
+    XKc_Cyrillic_JE* = 0x000006B8
+    XKc_Serbian_JE* = 0x000006B8 # deprecated 
+    XKc_Cyrillic_LJE* = 0x000006B9
+    XKc_Serbian_LJE* = 0x000006B9 # deprecated 
+    XKc_Cyrillic_NJE* = 0x000006BA
+    XKc_Serbian_NJE* = 0x000006BA # deprecated 
+    XKc_Serbian_TSHE* = 0x000006BB
+    XKc_Macedonia_KJE* = 0x000006BC
+    XKc_Ukrainian_GHE_WITH_UPTURN* = 0x000006BD
+    XKc_Byelorussian_SHORTU* = 0x000006BE
+    XKc_Cyrillic_DZHE* = 0x000006BF
+    XKc_Serbian_DZE* = 0x000006BF # deprecated 
+    XK_Cyrillic_yu* = 0x000006C0
+    XK_Cyrillic_a* = 0x000006C1
+    XK_Cyrillic_be* = 0x000006C2
+    XK_Cyrillic_tse* = 0x000006C3
+    XK_Cyrillic_de* = 0x000006C4
+    XK_Cyrillic_ie* = 0x000006C5
+    XK_Cyrillic_ef* = 0x000006C6
+    XK_Cyrillic_ghe* = 0x000006C7
+    XK_Cyrillic_ha* = 0x000006C8
+    XK_Cyrillic_i* = 0x000006C9
+    XK_Cyrillic_shorti* = 0x000006CA
+    XK_Cyrillic_ka* = 0x000006CB
+    XK_Cyrillic_el* = 0x000006CC
+    XK_Cyrillic_em* = 0x000006CD
+    XK_Cyrillic_en* = 0x000006CE
+    XK_Cyrillic_o* = 0x000006CF
+    XK_Cyrillic_pe* = 0x000006D0
+    XK_Cyrillic_ya* = 0x000006D1
+    XK_Cyrillic_er* = 0x000006D2
+    XK_Cyrillic_es* = 0x000006D3
+    XK_Cyrillic_te* = 0x000006D4
+    XK_Cyrillic_u* = 0x000006D5
+    XK_Cyrillic_zhe* = 0x000006D6
+    XK_Cyrillic_ve* = 0x000006D7
+    XK_Cyrillic_softsign* = 0x000006D8
+    XK_Cyrillic_yeru* = 0x000006D9
+    XK_Cyrillic_ze* = 0x000006DA
+    XK_Cyrillic_sha* = 0x000006DB
+    XK_Cyrillic_e* = 0x000006DC
+    XK_Cyrillic_shcha* = 0x000006DD
+    XK_Cyrillic_che* = 0x000006DE
+    XK_Cyrillic_hardsign* = 0x000006DF
+    XKc_Cyrillic_YU* = 0x000006E0
+    XKc_Cyrillic_A* = 0x000006E1
+    XKc_Cyrillic_BE* = 0x000006E2
+    XKc_Cyrillic_TSE* = 0x000006E3
+    XKc_Cyrillic_DE* = 0x000006E4
+    XKc_Cyrillic_IE* = 0x000006E5
+    XKc_Cyrillic_EF* = 0x000006E6
+    XKc_Cyrillic_GHE* = 0x000006E7
+    XKc_Cyrillic_HA* = 0x000006E8
+    XKc_Cyrillic_I* = 0x000006E9
+    XKc_Cyrillic_SHORTI* = 0x000006EA
+    XKc_Cyrillic_KA* = 0x000006EB
+    XKc_Cyrillic_EL* = 0x000006EC
+    XKc_Cyrillic_EM* = 0x000006ED
+    XKc_Cyrillic_EN* = 0x000006EE
+    XKc_Cyrillic_O* = 0x000006EF
+    XKc_Cyrillic_PE* = 0x000006F0
+    XKc_Cyrillic_YA* = 0x000006F1
+    XKc_Cyrillic_ER* = 0x000006F2
+    XKc_Cyrillic_ES* = 0x000006F3
+    XKc_Cyrillic_TE* = 0x000006F4
+    XKc_Cyrillic_U* = 0x000006F5
+    XKc_Cyrillic_ZHE* = 0x000006F6
+    XKc_Cyrillic_VE* = 0x000006F7
+    XKc_Cyrillic_SOFTSIGN* = 0x000006F8
+    XKc_Cyrillic_YERU* = 0x000006F9
+    XKc_Cyrillic_ZE* = 0x000006FA
+    XKc_Cyrillic_SHA* = 0x000006FB
+    XKc_Cyrillic_E* = 0x000006FC
+    XKc_Cyrillic_SHCHA* = 0x000006FD
+    XKc_Cyrillic_CHE* = 0x000006FE
+    XKc_Cyrillic_HARDSIGN* = 0x000006FF
+# XK_CYRILLIC 
+#*
+# * Greek
+# * Byte 3 = 7
+# *
+
+when defined(XK_GREEK) or true: 
+  const
+    XKc_Greek_ALPHAaccent* = 0x000007A1
+    XKc_Greek_EPSILONaccent* = 0x000007A2
+    XKc_Greek_ETAaccent* = 0x000007A3
+    XKc_Greek_IOTAaccent* = 0x000007A4
+    XKc_Greek_IOTAdieresis* = 0x000007A5
+    XKc_Greek_IOTAdiaeresis* = XKc_Greek_IOTAdieresis # old typo 
+    XKc_Greek_OMICRONaccent* = 0x000007A7
+    XKc_Greek_UPSILONaccent* = 0x000007A8
+    XKc_Greek_UPSILONdieresis* = 0x000007A9
+    XKc_Greek_OMEGAaccent* = 0x000007AB
+    XK_Greek_accentdieresis* = 0x000007AE
+    XK_Greek_horizbar* = 0x000007AF
+    XK_Greek_alphaaccent* = 0x000007B1
+    XK_Greek_epsilonaccent* = 0x000007B2
+    XK_Greek_etaaccent* = 0x000007B3
+    XK_Greek_iotaaccent* = 0x000007B4
+    XK_Greek_iotadieresis* = 0x000007B5
+    XK_Greek_iotaaccentdieresis* = 0x000007B6
+    XK_Greek_omicronaccent* = 0x000007B7
+    XK_Greek_upsilonaccent* = 0x000007B8
+    XK_Greek_upsilondieresis* = 0x000007B9
+    XK_Greek_upsilonaccentdieresis* = 0x000007BA
+    XK_Greek_omegaaccent* = 0x000007BB
+    XKc_Greek_ALPHA* = 0x000007C1
+    XKc_Greek_BETA* = 0x000007C2
+    XKc_Greek_GAMMA* = 0x000007C3
+    XKc_Greek_DELTA* = 0x000007C4
+    XKc_Greek_EPSILON* = 0x000007C5
+    XKc_Greek_ZETA* = 0x000007C6
+    XKc_Greek_ETA* = 0x000007C7
+    XKc_Greek_THETA* = 0x000007C8
+    XKc_Greek_IOTA* = 0x000007C9
+    XKc_Greek_KAPPA* = 0x000007CA
+    XKc_Greek_LAMDA* = 0x000007CB
+    XKc_Greek_LAMBDA* = 0x000007CB
+    XKc_Greek_MU* = 0x000007CC
+    XKc_Greek_NU* = 0x000007CD
+    XKc_Greek_XI* = 0x000007CE
+    XKc_Greek_OMICRON* = 0x000007CF
+    XKc_Greek_PI* = 0x000007D0
+    XKc_Greek_RHO* = 0x000007D1
+    XKc_Greek_SIGMA* = 0x000007D2
+    XKc_Greek_TAU* = 0x000007D4
+    XKc_Greek_UPSILON* = 0x000007D5
+    XKc_Greek_PHI* = 0x000007D6
+    XKc_Greek_CHI* = 0x000007D7
+    XKc_Greek_PSI* = 0x000007D8
+    XKc_Greek_OMEGA* = 0x000007D9
+    XK_Greek_alpha* = 0x000007E1
+    XK_Greek_beta* = 0x000007E2
+    XK_Greek_gamma* = 0x000007E3
+    XK_Greek_delta* = 0x000007E4
+    XK_Greek_epsilon* = 0x000007E5
+    XK_Greek_zeta* = 0x000007E6
+    XK_Greek_eta* = 0x000007E7
+    XK_Greek_theta* = 0x000007E8
+    XK_Greek_iota* = 0x000007E9
+    XK_Greek_kappa* = 0x000007EA
+    XK_Greek_lamda* = 0x000007EB
+    XK_Greek_lambda* = 0x000007EB
+    XK_Greek_mu* = 0x000007EC
+    XK_Greek_nu* = 0x000007ED
+    XK_Greek_xi* = 0x000007EE
+    XK_Greek_omicron* = 0x000007EF
+    XK_Greek_pi* = 0x000007F0
+    XK_Greek_rho* = 0x000007F1
+    XK_Greek_sigma* = 0x000007F2
+    XK_Greek_finalsmallsigma* = 0x000007F3
+    XK_Greek_tau* = 0x000007F4
+    XK_Greek_upsilon* = 0x000007F5
+    XK_Greek_phi* = 0x000007F6
+    XK_Greek_chi* = 0x000007F7
+    XK_Greek_psi* = 0x000007F8
+    XK_Greek_omega* = 0x000007F9
+    XK_Greek_switch* = 0x0000FF7E # Alias for mode_switch 
+# XK_GREEK 
+#*
+# * Technical
+# * Byte 3 = 8
+# *
+
+when defined(XK_TECHNICAL) or true: 
+  const
+    XK_leftradical* = 0x000008A1
+    XK_topleftradical* = 0x000008A2
+    XK_horizconnector* = 0x000008A3
+    XK_topintegral* = 0x000008A4
+    XK_botintegral* = 0x000008A5
+    XK_vertconnector* = 0x000008A6
+    XK_topleftsqbracket* = 0x000008A7
+    XK_botleftsqbracket* = 0x000008A8
+    XK_toprightsqbracket* = 0x000008A9
+    XK_botrightsqbracket* = 0x000008AA
+    XK_topleftparens* = 0x000008AB
+    XK_botleftparens* = 0x000008AC
+    XK_toprightparens* = 0x000008AD
+    XK_botrightparens* = 0x000008AE
+    XK_leftmiddlecurlybrace* = 0x000008AF
+    XK_rightmiddlecurlybrace* = 0x000008B0
+    XK_topleftsummation* = 0x000008B1
+    XK_botleftsummation* = 0x000008B2
+    XK_topvertsummationconnector* = 0x000008B3
+    XK_botvertsummationconnector* = 0x000008B4
+    XK_toprightsummation* = 0x000008B5
+    XK_botrightsummation* = 0x000008B6
+    XK_rightmiddlesummation* = 0x000008B7
+    XK_lessthanequal* = 0x000008BC
+    XK_notequal* = 0x000008BD
+    XK_greaterthanequal* = 0x000008BE
+    XK_integral* = 0x000008BF
+    XK_therefore* = 0x000008C0
+    XK_variation* = 0x000008C1
+    XK_infinity* = 0x000008C2
+    XK_nabla* = 0x000008C5
+    XK_approximate* = 0x000008C8
+    XK_similarequal* = 0x000008C9
+    XK_ifonlyif* = 0x000008CD
+    XK_implies* = 0x000008CE
+    XK_identical* = 0x000008CF
+    XK_radical* = 0x000008D6
+    XK_includedin* = 0x000008DA
+    XK_includes* = 0x000008DB
+    XK_intersection* = 0x000008DC
+    XK_union* = 0x000008DD
+    XK_logicaland* = 0x000008DE
+    XK_logicalor* = 0x000008DF
+    XK_partialderivative* = 0x000008EF
+    XK_function* = 0x000008F6
+    XK_leftarrow* = 0x000008FB
+    XK_uparrow* = 0x000008FC
+    XK_rightarrow* = 0x000008FD
+    XK_downarrow* = 0x000008FE
+# XK_TECHNICAL 
+#*
+# *  Special
+# *  Byte 3 = 9
+# *
+
+when defined(XK_SPECIAL): 
+  const
+    XK_blank* = 0x000009DF
+    XK_soliddiamond* = 0x000009E0
+    XK_checkerboard* = 0x000009E1
+    XK_ht* = 0x000009E2
+    XK_ff* = 0x000009E3
+    XK_cr* = 0x000009E4
+    XK_lf* = 0x000009E5
+    XK_nl* = 0x000009E8
+    XK_vt* = 0x000009E9
+    XK_lowrightcorner* = 0x000009EA
+    XK_uprightcorner* = 0x000009EB
+    XK_upleftcorner* = 0x000009EC
+    XK_lowleftcorner* = 0x000009ED
+    XK_crossinglines* = 0x000009EE
+    XK_horizlinescan1* = 0x000009EF
+    XK_horizlinescan3* = 0x000009F0
+    XK_horizlinescan5* = 0x000009F1
+    XK_horizlinescan7* = 0x000009F2
+    XK_horizlinescan9* = 0x000009F3
+    XK_leftt* = 0x000009F4
+    XK_rightt* = 0x000009F5
+    XK_bott* = 0x000009F6
+    XK_topt* = 0x000009F7
+    XK_vertbar* = 0x000009F8
+# XK_SPECIAL 
+#*
+# *  Publishing
+# *  Byte 3 = a
+# *
+
+when defined(XK_PUBLISHING) or true: 
+  const
+    XK_emspace* = 0x00000AA1
+    XK_enspace* = 0x00000AA2
+    XK_em3space* = 0x00000AA3
+    XK_em4space* = 0x00000AA4
+    XK_digitspace* = 0x00000AA5
+    XK_punctspace* = 0x00000AA6
+    XK_thinspace* = 0x00000AA7
+    XK_hairspace* = 0x00000AA8
+    XK_emdash* = 0x00000AA9
+    XK_endash* = 0x00000AAA
+    XK_signifblank* = 0x00000AAC
+    XK_ellipsis* = 0x00000AAE
+    XK_doubbaselinedot* = 0x00000AAF
+    XK_onethird* = 0x00000AB0
+    XK_twothirds* = 0x00000AB1
+    XK_onefifth* = 0x00000AB2
+    XK_twofifths* = 0x00000AB3
+    XK_threefifths* = 0x00000AB4
+    XK_fourfifths* = 0x00000AB5
+    XK_onesixth* = 0x00000AB6
+    XK_fivesixths* = 0x00000AB7
+    XK_careof* = 0x00000AB8
+    XK_figdash* = 0x00000ABB
+    XK_leftanglebracket* = 0x00000ABC
+    XK_decimalpoint* = 0x00000ABD
+    XK_rightanglebracket* = 0x00000ABE
+    XK_marker* = 0x00000ABF
+    XK_oneeighth* = 0x00000AC3
+    XK_threeeighths* = 0x00000AC4
+    XK_fiveeighths* = 0x00000AC5
+    XK_seveneighths* = 0x00000AC6
+    XK_trademark* = 0x00000AC9
+    XK_signaturemark* = 0x00000ACA
+    XK_trademarkincircle* = 0x00000ACB
+    XK_leftopentriangle* = 0x00000ACC
+    XK_rightopentriangle* = 0x00000ACD
+    XK_emopencircle* = 0x00000ACE
+    XK_emopenrectangle* = 0x00000ACF
+    XK_leftsinglequotemark* = 0x00000AD0
+    XK_rightsinglequotemark* = 0x00000AD1
+    XK_leftdoublequotemark* = 0x00000AD2
+    XK_rightdoublequotemark* = 0x00000AD3
+    XK_prescription* = 0x00000AD4
+    XK_minutes* = 0x00000AD6
+    XK_seconds* = 0x00000AD7
+    XK_latincross* = 0x00000AD9
+    XK_hexagram* = 0x00000ADA
+    XK_filledrectbullet* = 0x00000ADB
+    XK_filledlefttribullet* = 0x00000ADC
+    XK_filledrighttribullet* = 0x00000ADD
+    XK_emfilledcircle* = 0x00000ADE
+    XK_emfilledrect* = 0x00000ADF
+    XK_enopencircbullet* = 0x00000AE0
+    XK_enopensquarebullet* = 0x00000AE1
+    XK_openrectbullet* = 0x00000AE2
+    XK_opentribulletup* = 0x00000AE3
+    XK_opentribulletdown* = 0x00000AE4
+    XK_openstar* = 0x00000AE5
+    XK_enfilledcircbullet* = 0x00000AE6
+    XK_enfilledsqbullet* = 0x00000AE7
+    XK_filledtribulletup* = 0x00000AE8
+    XK_filledtribulletdown* = 0x00000AE9
+    XK_leftpointer* = 0x00000AEA
+    XK_rightpointer* = 0x00000AEB
+    XK_club* = 0x00000AEC
+    XK_diamond* = 0x00000AED
+    XK_heart* = 0x00000AEE
+    XK_maltesecross* = 0x00000AF0
+    XK_dagger* = 0x00000AF1
+    XK_doubledagger* = 0x00000AF2
+    XK_checkmark* = 0x00000AF3
+    XK_ballotcross* = 0x00000AF4
+    XK_musicalsharp* = 0x00000AF5
+    XK_musicalflat* = 0x00000AF6
+    XK_malesymbol* = 0x00000AF7
+    XK_femalesymbol* = 0x00000AF8
+    XK_telephone* = 0x00000AF9
+    XK_telephonerecorder* = 0x00000AFA
+    XK_phonographcopyright* = 0x00000AFB
+    XK_caret* = 0x00000AFC
+    XK_singlelowquotemark* = 0x00000AFD
+    XK_doublelowquotemark* = 0x00000AFE
+    XK_cursor* = 0x00000AFF
+# XK_PUBLISHING 
+#*
+# *  APL
+# *  Byte 3 = b
+# *
+
+when defined(XK_APL) or true: 
+  const
+    XK_leftcaret* = 0x00000BA3
+    XK_rightcaret* = 0x00000BA6
+    XK_downcaret* = 0x00000BA8
+    XK_upcaret* = 0x00000BA9
+    XK_overbar* = 0x00000BC0
+    XK_downtack* = 0x00000BC2
+    XK_upshoe* = 0x00000BC3
+    XK_downstile* = 0x00000BC4
+    XK_underbar* = 0x00000BC6
+    XK_jot* = 0x00000BCA
+    XK_quad* = 0x00000BCC
+    XK_uptack* = 0x00000BCE
+    XK_circle* = 0x00000BCF
+    XK_upstile* = 0x00000BD3
+    XK_downshoe* = 0x00000BD6
+    XK_rightshoe* = 0x00000BD8
+    XK_leftshoe* = 0x00000BDA
+    XK_lefttack* = 0x00000BDC
+    XK_righttack* = 0x00000BFC
+# XK_APL 
+#*
+# * Hebrew
+# * Byte 3 = c
+# *
+
+when defined(XK_HEBREW) or true: 
+  const
+    XK_hebrew_doublelowline* = 0x00000CDF
+    XK_hebrew_aleph* = 0x00000CE0
+    XK_hebrew_bet* = 0x00000CE1
+    XK_hebrew_beth* = 0x00000CE1 # deprecated 
+    XK_hebrew_gimel* = 0x00000CE2
+    XK_hebrew_gimmel* = 0x00000CE2 # deprecated 
+    XK_hebrew_dalet* = 0x00000CE3
+    XK_hebrew_daleth* = 0x00000CE3 # deprecated 
+    XK_hebrew_he* = 0x00000CE4
+    XK_hebrew_waw* = 0x00000CE5
+    XK_hebrew_zain* = 0x00000CE6
+    XK_hebrew_zayin* = 0x00000CE6 # deprecated 
+    XK_hebrew_chet* = 0x00000CE7
+    XK_hebrew_het* = 0x00000CE7 # deprecated 
+    XK_hebrew_tet* = 0x00000CE8
+    XK_hebrew_teth* = 0x00000CE8 # deprecated 
+    XK_hebrew_yod* = 0x00000CE9
+    XK_hebrew_finalkaph* = 0x00000CEA
+    XK_hebrew_kaph* = 0x00000CEB
+    XK_hebrew_lamed* = 0x00000CEC
+    XK_hebrew_finalmem* = 0x00000CED
+    XK_hebrew_mem* = 0x00000CEE
+    XK_hebrew_finalnun* = 0x00000CEF
+    XK_hebrew_nun* = 0x00000CF0
+    XK_hebrew_samech* = 0x00000CF1
+    XK_hebrew_samekh* = 0x00000CF1 # deprecated 
+    XK_hebrew_ayin* = 0x00000CF2
+    XK_hebrew_finalpe* = 0x00000CF3
+    XK_hebrew_pe* = 0x00000CF4
+    XK_hebrew_finalzade* = 0x00000CF5
+    XK_hebrew_finalzadi* = 0x00000CF5 # deprecated 
+    XK_hebrew_zade* = 0x00000CF6
+    XK_hebrew_zadi* = 0x00000CF6 # deprecated 
+    XK_hebrew_qoph* = 0x00000CF7
+    XK_hebrew_kuf* = 0x00000CF7 # deprecated 
+    XK_hebrew_resh* = 0x00000CF8
+    XK_hebrew_shin* = 0x00000CF9
+    XK_hebrew_taw* = 0x00000CFA
+    XK_hebrew_taf* = 0x00000CFA # deprecated 
+    XK_Hebrew_switch* = 0x0000FF7E # Alias for mode_switch 
+# XK_HEBREW 
+#*
+# * Thai
+# * Byte 3 = d
+# *
+
+when defined(XK_THAI) or true: 
+  const
+    XK_Thai_kokai* = 0x00000DA1
+    XK_Thai_khokhai* = 0x00000DA2
+    XK_Thai_khokhuat* = 0x00000DA3
+    XK_Thai_khokhwai* = 0x00000DA4
+    XK_Thai_khokhon* = 0x00000DA5
+    XK_Thai_khorakhang* = 0x00000DA6
+    XK_Thai_ngongu* = 0x00000DA7
+    XK_Thai_chochan* = 0x00000DA8
+    XK_Thai_choching* = 0x00000DA9
+    XK_Thai_chochang* = 0x00000DAA
+    XK_Thai_soso* = 0x00000DAB
+    XK_Thai_chochoe* = 0x00000DAC
+    XK_Thai_yoying* = 0x00000DAD
+    XK_Thai_dochada* = 0x00000DAE
+    XK_Thai_topatak* = 0x00000DAF
+    XK_Thai_thothan* = 0x00000DB0
+    XK_Thai_thonangmontho* = 0x00000DB1
+    XK_Thai_thophuthao* = 0x00000DB2
+    XK_Thai_nonen* = 0x00000DB3
+    XK_Thai_dodek* = 0x00000DB4
+    XK_Thai_totao* = 0x00000DB5
+    XK_Thai_thothung* = 0x00000DB6
+    XK_Thai_thothahan* = 0x00000DB7
+    XK_Thai_thothong* = 0x00000DB8
+    XK_Thai_nonu* = 0x00000DB9
+    XK_Thai_bobaimai* = 0x00000DBA
+    XK_Thai_popla* = 0x00000DBB
+    XK_Thai_phophung* = 0x00000DBC
+    XK_Thai_fofa* = 0x00000DBD
+    XK_Thai_phophan* = 0x00000DBE
+    XK_Thai_fofan* = 0x00000DBF
+    XK_Thai_phosamphao* = 0x00000DC0
+    XK_Thai_moma* = 0x00000DC1
+    XK_Thai_yoyak* = 0x00000DC2
+    XK_Thai_rorua* = 0x00000DC3
+    XK_Thai_ru* = 0x00000DC4
+    XK_Thai_loling* = 0x00000DC5
+    XK_Thai_lu* = 0x00000DC6
+    XK_Thai_wowaen* = 0x00000DC7
+    XK_Thai_sosala* = 0x00000DC8
+    XK_Thai_sorusi* = 0x00000DC9
+    XK_Thai_sosua* = 0x00000DCA
+    XK_Thai_hohip* = 0x00000DCB
+    XK_Thai_lochula* = 0x00000DCC
+    XK_Thai_oang* = 0x00000DCD
+    XK_Thai_honokhuk* = 0x00000DCE
+    XK_Thai_paiyannoi* = 0x00000DCF
+    XK_Thai_saraa* = 0x00000DD0
+    XK_Thai_maihanakat* = 0x00000DD1
+    XK_Thai_saraaa* = 0x00000DD2
+    XK_Thai_saraam* = 0x00000DD3
+    XK_Thai_sarai* = 0x00000DD4
+    XK_Thai_saraii* = 0x00000DD5
+    XK_Thai_saraue* = 0x00000DD6
+    XK_Thai_sarauee* = 0x00000DD7
+    XK_Thai_sarau* = 0x00000DD8
+    XK_Thai_sarauu* = 0x00000DD9
+    XK_Thai_phinthu* = 0x00000DDA
+    XK_Thai_maihanakat_maitho* = 0x00000DDE
+    XK_Thai_baht* = 0x00000DDF
+    XK_Thai_sarae* = 0x00000DE0
+    XK_Thai_saraae* = 0x00000DE1
+    XK_Thai_sarao* = 0x00000DE2
+    XK_Thai_saraaimaimuan* = 0x00000DE3
+    XK_Thai_saraaimaimalai* = 0x00000DE4
+    XK_Thai_lakkhangyao* = 0x00000DE5
+    XK_Thai_maiyamok* = 0x00000DE6
+    XK_Thai_maitaikhu* = 0x00000DE7
+    XK_Thai_maiek* = 0x00000DE8
+    XK_Thai_maitho* = 0x00000DE9
+    XK_Thai_maitri* = 0x00000DEA
+    XK_Thai_maichattawa* = 0x00000DEB
+    XK_Thai_thanthakhat* = 0x00000DEC
+    XK_Thai_nikhahit* = 0x00000DED
+    XK_Thai_leksun* = 0x00000DF0
+    XK_Thai_leknung* = 0x00000DF1
+    XK_Thai_leksong* = 0x00000DF2
+    XK_Thai_leksam* = 0x00000DF3
+    XK_Thai_leksi* = 0x00000DF4
+    XK_Thai_lekha* = 0x00000DF5
+    XK_Thai_lekhok* = 0x00000DF6
+    XK_Thai_lekchet* = 0x00000DF7
+    XK_Thai_lekpaet* = 0x00000DF8
+    XK_Thai_lekkao* = 0x00000DF9
+# XK_THAI 
+#*
+# *   Korean
+# *   Byte 3 = e
+# *
+
+when defined(XK_KOREAN) or true: 
+  const
+    XK_Hangul* = 0x0000FF31     # Hangul start/stop(toggle) 
+    XK_Hangul_Start* = 0x0000FF32 # Hangul start 
+    XK_Hangul_End* = 0x0000FF33 # Hangul end, English start 
+    XK_Hangul_Hanja* = 0x0000FF34 # Start Hangul->Hanja Conversion 
+    XK_Hangul_Jamo* = 0x0000FF35 # Hangul Jamo mode 
+    XK_Hangul_Romaja* = 0x0000FF36 # Hangul Romaja mode 
+    XK_Hangul_Codeinput* = 0x0000FF37 # Hangul code input mode 
+    XK_Hangul_Jeonja* = 0x0000FF38 # Jeonja mode 
+    XK_Hangul_Banja* = 0x0000FF39 # Banja mode 
+    XK_Hangul_PreHanja* = 0x0000FF3A # Pre Hanja conversion 
+    XK_Hangul_PostHanja* = 0x0000FF3B # Post Hanja conversion 
+    XK_Hangul_SingleCandidate* = 0x0000FF3C # Single candidate 
+    XK_Hangul_MultipleCandidate* = 0x0000FF3D # Multiple candidate 
+    XK_Hangul_PreviousCandidate* = 0x0000FF3E # Previous candidate 
+    XK_Hangul_Special* = 0x0000FF3F # Special symbols 
+    XK_Hangul_switch* = 0x0000FF7E # Alias for mode_switch 
+                                   # Hangul Consonant Characters 
+    XK_Hangul_Kiyeog* = 0x00000EA1
+    XK_Hangul_SsangKiyeog* = 0x00000EA2
+    XK_Hangul_KiyeogSios* = 0x00000EA3
+    XK_Hangul_Nieun* = 0x00000EA4
+    XK_Hangul_NieunJieuj* = 0x00000EA5
+    XK_Hangul_NieunHieuh* = 0x00000EA6
+    XK_Hangul_Dikeud* = 0x00000EA7
+    XK_Hangul_SsangDikeud* = 0x00000EA8
+    XK_Hangul_Rieul* = 0x00000EA9
+    XK_Hangul_RieulKiyeog* = 0x00000EAA
+    XK_Hangul_RieulMieum* = 0x00000EAB
+    XK_Hangul_RieulPieub* = 0x00000EAC
+    XK_Hangul_RieulSios* = 0x00000EAD
+    XK_Hangul_RieulTieut* = 0x00000EAE
+    XK_Hangul_RieulPhieuf* = 0x00000EAF
+    XK_Hangul_RieulHieuh* = 0x00000EB0
+    XK_Hangul_Mieum* = 0x00000EB1
+    XK_Hangul_Pieub* = 0x00000EB2
+    XK_Hangul_SsangPieub* = 0x00000EB3
+    XK_Hangul_PieubSios* = 0x00000EB4
+    XK_Hangul_Sios* = 0x00000EB5
+    XK_Hangul_SsangSios* = 0x00000EB6
+    XK_Hangul_Ieung* = 0x00000EB7
+    XK_Hangul_Jieuj* = 0x00000EB8
+    XK_Hangul_SsangJieuj* = 0x00000EB9
+    XK_Hangul_Cieuc* = 0x00000EBA
+    XK_Hangul_Khieuq* = 0x00000EBB
+    XK_Hangul_Tieut* = 0x00000EBC
+    XK_Hangul_Phieuf* = 0x00000EBD
+    XK_Hangul_Hieuh* = 0x00000EBE # Hangul Vowel Characters 
+    XK_Hangul_A* = 0x00000EBF
+    XK_Hangul_AE* = 0x00000EC0
+    XK_Hangul_YA* = 0x00000EC1
+    XK_Hangul_YAE* = 0x00000EC2
+    XK_Hangul_EO* = 0x00000EC3
+    XK_Hangul_E* = 0x00000EC4
+    XK_Hangul_YEO* = 0x00000EC5
+    XK_Hangul_YE* = 0x00000EC6
+    XK_Hangul_O* = 0x00000EC7
+    XK_Hangul_WA* = 0x00000EC8
+    XK_Hangul_WAE* = 0x00000EC9
+    XK_Hangul_OE* = 0x00000ECA
+    XK_Hangul_YO* = 0x00000ECB
+    XK_Hangul_U* = 0x00000ECC
+    XK_Hangul_WEO* = 0x00000ECD
+    XK_Hangul_WE* = 0x00000ECE
+    XK_Hangul_WI* = 0x00000ECF
+    XK_Hangul_YU* = 0x00000ED0
+    XK_Hangul_EU* = 0x00000ED1
+    XK_Hangul_YI* = 0x00000ED2
+    XK_Hangul_I* = 0x00000ED3   # Hangul syllable-final (JongSeong) Characters 
+    XK_Hangul_J_Kiyeog* = 0x00000ED4
+    XK_Hangul_J_SsangKiyeog* = 0x00000ED5
+    XK_Hangul_J_KiyeogSios* = 0x00000ED6
+    XK_Hangul_J_Nieun* = 0x00000ED7
+    XK_Hangul_J_NieunJieuj* = 0x00000ED8
+    XK_Hangul_J_NieunHieuh* = 0x00000ED9
+    XK_Hangul_J_Dikeud* = 0x00000EDA
+    XK_Hangul_J_Rieul* = 0x00000EDB
+    XK_Hangul_J_RieulKiyeog* = 0x00000EDC
+    XK_Hangul_J_RieulMieum* = 0x00000EDD
+    XK_Hangul_J_RieulPieub* = 0x00000EDE
+    XK_Hangul_J_RieulSios* = 0x00000EDF
+    XK_Hangul_J_RieulTieut* = 0x00000EE0
+    XK_Hangul_J_RieulPhieuf* = 0x00000EE1
+    XK_Hangul_J_RieulHieuh* = 0x00000EE2
+    XK_Hangul_J_Mieum* = 0x00000EE3
+    XK_Hangul_J_Pieub* = 0x00000EE4
+    XK_Hangul_J_PieubSios* = 0x00000EE5
+    XK_Hangul_J_Sios* = 0x00000EE6
+    XK_Hangul_J_SsangSios* = 0x00000EE7
+    XK_Hangul_J_Ieung* = 0x00000EE8
+    XK_Hangul_J_Jieuj* = 0x00000EE9
+    XK_Hangul_J_Cieuc* = 0x00000EEA
+    XK_Hangul_J_Khieuq* = 0x00000EEB
+    XK_Hangul_J_Tieut* = 0x00000EEC
+    XK_Hangul_J_Phieuf* = 0x00000EED
+    XK_Hangul_J_Hieuh* = 0x00000EEE # Ancient Hangul Consonant Characters 
+    XK_Hangul_RieulYeorinHieuh* = 0x00000EEF
+    XK_Hangul_SunkyeongeumMieum* = 0x00000EF0
+    XK_Hangul_SunkyeongeumPieub* = 0x00000EF1
+    XK_Hangul_PanSios* = 0x00000EF2
+    XK_Hangul_KkogjiDalrinIeung* = 0x00000EF3
+    XK_Hangul_SunkyeongeumPhieuf* = 0x00000EF4
+    XK_Hangul_YeorinHieuh* = 0x00000EF5 # Ancient Hangul Vowel Characters 
+    XK_Hangul_AraeA* = 0x00000EF6
+    XK_Hangul_AraeAE* = 0x00000EF7 # Ancient Hangul syllable-final (JongSeong) Characters 
+    XK_Hangul_J_PanSios* = 0x00000EF8
+    XK_Hangul_J_KkogjiDalrinIeung* = 0x00000EF9
+    XK_Hangul_J_YeorinHieuh* = 0x00000EFA # Korean currency symbol 
+    XK_Korean_Won* = 0x00000EFF
+# XK_KOREAN 
+#*
+# *   Armenian
+# *   Byte 3 = = $14
+# *
+
+when defined(XK_ARMENIAN) or true: 
+  const
+    XK_Armenian_eternity* = 0x000014A1
+    XK_Armenian_ligature_ew* = 0x000014A2
+    XK_Armenian_full_stop* = 0x000014A3
+    XK_Armenian_verjaket* = 0x000014A3
+    XK_Armenian_parenright* = 0x000014A4
+    XK_Armenian_parenleft* = 0x000014A5
+    XK_Armenian_guillemotright* = 0x000014A6
+    XK_Armenian_guillemotleft* = 0x000014A7
+    XK_Armenian_em_dash* = 0x000014A8
+    XK_Armenian_dot* = 0x000014A9
+    XK_Armenian_mijaket* = 0x000014A9
+    XK_Armenian_separation_mark* = 0x000014AA
+    XK_Armenian_but* = 0x000014AA
+    XK_Armenian_comma* = 0x000014AB
+    XK_Armenian_en_dash* = 0x000014AC
+    XK_Armenian_hyphen* = 0x000014AD
+    XK_Armenian_yentamna* = 0x000014AD
+    XK_Armenian_ellipsis* = 0x000014AE
+    XK_Armenian_exclam* = 0x000014AF
+    XK_Armenian_amanak* = 0x000014AF
+    XK_Armenian_accent* = 0x000014B0
+    XK_Armenian_shesht* = 0x000014B0
+    XK_Armenian_question* = 0x000014B1
+    XK_Armenian_paruyk* = 0x000014B1
+    XKc_Armenian_AYB* = 0x000014B2
+    XK_Armenian_ayb* = 0x000014B3
+    XKc_Armenian_BEN* = 0x000014B4
+    XK_Armenian_ben* = 0x000014B5
+    XKc_Armenian_GIM* = 0x000014B6
+    XK_Armenian_gim* = 0x000014B7
+    XKc_Armenian_DA* = 0x000014B8
+    XK_Armenian_da* = 0x000014B9
+    XKc_Armenian_YECH* = 0x000014BA
+    XK_Armenian_yech* = 0x000014BB
+    XKc_Armenian_ZA* = 0x000014BC
+    XK_Armenian_za* = 0x000014BD
+    XKc_Armenian_E* = 0x000014BE
+    XK_Armenian_e* = 0x000014BF
+    XKc_Armenian_AT* = 0x000014C0
+    XK_Armenian_at* = 0x000014C1
+    XKc_Armenian_TO* = 0x000014C2
+    XK_Armenian_to* = 0x000014C3
+    XKc_Armenian_ZHE* = 0x000014C4
+    XK_Armenian_zhe* = 0x000014C5
+    XKc_Armenian_INI* = 0x000014C6
+    XK_Armenian_ini* = 0x000014C7
+    XKc_Armenian_LYUN* = 0x000014C8
+    XK_Armenian_lyun* = 0x000014C9
+    XKc_Armenian_KHE* = 0x000014CA
+    XK_Armenian_khe* = 0x000014CB
+    XKc_Armenian_TSA* = 0x000014CC
+    XK_Armenian_tsa* = 0x000014CD
+    XKc_Armenian_KEN* = 0x000014CE
+    XK_Armenian_ken* = 0x000014CF
+    XKc_Armenian_HO* = 0x000014D0
+    XK_Armenian_ho* = 0x000014D1
+    XKc_Armenian_DZA* = 0x000014D2
+    XK_Armenian_dza* = 0x000014D3
+    XKc_Armenian_GHAT* = 0x000014D4
+    XK_Armenian_ghat* = 0x000014D5
+    XKc_Armenian_TCHE* = 0x000014D6
+    XK_Armenian_tche* = 0x000014D7
+    XKc_Armenian_MEN* = 0x000014D8
+    XK_Armenian_men* = 0x000014D9
+    XKc_Armenian_HI* = 0x000014DA
+    XK_Armenian_hi* = 0x000014DB
+    XKc_Armenian_NU* = 0x000014DC
+    XK_Armenian_nu* = 0x000014DD
+    XKc_Armenian_SHA* = 0x000014DE
+    XK_Armenian_sha* = 0x000014DF
+    XKc_Armenian_VO* = 0x000014E0
+    XK_Armenian_vo* = 0x000014E1
+    XKc_Armenian_CHA* = 0x000014E2
+    XK_Armenian_cha* = 0x000014E3
+    XKc_Armenian_PE* = 0x000014E4
+    XK_Armenian_pe* = 0x000014E5
+    XKc_Armenian_JE* = 0x000014E6
+    XK_Armenian_je* = 0x000014E7
+    XKc_Armenian_RA* = 0x000014E8
+    XK_Armenian_ra* = 0x000014E9
+    XKc_Armenian_SE* = 0x000014EA
+    XK_Armenian_se* = 0x000014EB
+    XKc_Armenian_VEV* = 0x000014EC
+    XK_Armenian_vev* = 0x000014ED
+    XKc_Armenian_TYUN* = 0x000014EE
+    XK_Armenian_tyun* = 0x000014EF
+    XKc_Armenian_RE* = 0x000014F0
+    XK_Armenian_re* = 0x000014F1
+    XKc_Armenian_TSO* = 0x000014F2
+    XK_Armenian_tso* = 0x000014F3
+    XKc_Armenian_VYUN* = 0x000014F4
+    XK_Armenian_vyun* = 0x000014F5
+    XKc_Armenian_PYUR* = 0x000014F6
+    XK_Armenian_pyur* = 0x000014F7
+    XKc_Armenian_KE* = 0x000014F8
+    XK_Armenian_ke* = 0x000014F9
+    XKc_Armenian_O* = 0x000014FA
+    XK_Armenian_o* = 0x000014FB
+    XKc_Armenian_FE* = 0x000014FC
+    XK_Armenian_fe* = 0x000014FD
+    XK_Armenian_apostrophe* = 0x000014FE
+    XK_Armenian_section_sign* = 0x000014FF
+# XK_ARMENIAN 
+#*
+# *   Georgian
+# *   Byte 3 = = $15
+# *
+
+when defined(XK_GEORGIAN) or true: 
+  const
+    XK_Georgian_an* = 0x000015D0
+    XK_Georgian_ban* = 0x000015D1
+    XK_Georgian_gan* = 0x000015D2
+    XK_Georgian_don* = 0x000015D3
+    XK_Georgian_en* = 0x000015D4
+    XK_Georgian_vin* = 0x000015D5
+    XK_Georgian_zen* = 0x000015D6
+    XK_Georgian_tan* = 0x000015D7
+    XK_Georgian_in* = 0x000015D8
+    XK_Georgian_kan* = 0x000015D9
+    XK_Georgian_las* = 0x000015DA
+    XK_Georgian_man* = 0x000015DB
+    XK_Georgian_nar* = 0x000015DC
+    XK_Georgian_on* = 0x000015DD
+    XK_Georgian_par* = 0x000015DE
+    XK_Georgian_zhar* = 0x000015DF
+    XK_Georgian_rae* = 0x000015E0
+    XK_Georgian_san* = 0x000015E1
+    XK_Georgian_tar* = 0x000015E2
+    XK_Georgian_un* = 0x000015E3
+    XK_Georgian_phar* = 0x000015E4
+    XK_Georgian_khar* = 0x000015E5
+    XK_Georgian_ghan* = 0x000015E6
+    XK_Georgian_qar* = 0x000015E7
+    XK_Georgian_shin* = 0x000015E8
+    XK_Georgian_chin* = 0x000015E9
+    XK_Georgian_can* = 0x000015EA
+    XK_Georgian_jil* = 0x000015EB
+    XK_Georgian_cil* = 0x000015EC
+    XK_Georgian_char* = 0x000015ED
+    XK_Georgian_xan* = 0x000015EE
+    XK_Georgian_jhan* = 0x000015EF
+    XK_Georgian_hae* = 0x000015F0
+    XK_Georgian_he* = 0x000015F1
+    XK_Georgian_hie* = 0x000015F2
+    XK_Georgian_we* = 0x000015F3
+    XK_Georgian_har* = 0x000015F4
+    XK_Georgian_hoe* = 0x000015F5
+    XK_Georgian_fi* = 0x000015F6
+# XK_GEORGIAN 
+#*
+# * Azeri (and other Turkic or Caucasian languages of ex-USSR)
+# * Byte 3 = = $16
+# *
+
+when defined(XK_CAUCASUS) or true: 
+  # latin 
+  const
+    XKc_Ccedillaabovedot* = 0x000016A2
+    XKc_Xabovedot* = 0x000016A3
+    XKc_Qabovedot* = 0x000016A5
+    XKc_Ibreve* = 0x000016A6
+    XKc_IE* = 0x000016A7
+    XKc_UO* = 0x000016A8
+    XKc_Zstroke* = 0x000016A9
+    XKc_Gcaron* = 0x000016AA
+    XKc_Obarred* = 0x000016AF
+    XK_ccedillaabovedot* = 0x000016B2
+    XK_xabovedot* = 0x000016B3
+    XKc_Ocaron* = 0x000016B4
+    XK_qabovedot* = 0x000016B5
+    XK_ibreve* = 0x000016B6
+    XK_ie* = 0x000016B7
+    XK_uo* = 0x000016B8
+    XK_zstroke* = 0x000016B9
+    XK_gcaron* = 0x000016BA
+    XK_ocaron* = 0x000016BD
+    XK_obarred* = 0x000016BF
+    XKc_SCHWA* = 0x000016C6
+    XK_schwa* = 0x000016F6 # those are not really Caucasus, but I put them here for now 
+                           # For Inupiak 
+    XKc_Lbelowdot* = 0x000016D1
+    XKc_Lstrokebelowdot* = 0x000016D2
+    XK_lbelowdot* = 0x000016E1
+    XK_lstrokebelowdot* = 0x000016E2 # For Guarani 
+    XKc_Gtilde* = 0x000016D3
+    XK_gtilde* = 0x000016E3
+# XK_CAUCASUS 
+#*
+# *   Vietnamese
+# *   Byte 3 = = $1e
+# *
+
+when defined(XK_VIETNAMESE) or true:
+  const 
+    XKc_Abelowdot* = 0x00001EA0
+    XK_abelowdot* = 0x00001EA1
+    XKc_Ahook* = 0x00001EA2
+    XK_ahook* = 0x00001EA3
+    XKc_Acircumflexacute* = 0x00001EA4
+    XK_acircumflexacute* = 0x00001EA5
+    XKc_Acircumflexgrave* = 0x00001EA6
+    XK_acircumflexgrave* = 0x00001EA7
+    XKc_Acircumflexhook* = 0x00001EA8
+    XK_acircumflexhook* = 0x00001EA9
+    XKc_Acircumflextilde* = 0x00001EAA
+    XK_acircumflextilde* = 0x00001EAB
+    XKc_Acircumflexbelowdot* = 0x00001EAC
+    XK_acircumflexbelowdot* = 0x00001EAD
+    XKc_Abreveacute* = 0x00001EAE
+    XK_abreveacute* = 0x00001EAF
+    XKc_Abrevegrave* = 0x00001EB0
+    XK_abrevegrave* = 0x00001EB1
+    XKc_Abrevehook* = 0x00001EB2
+    XK_abrevehook* = 0x00001EB3
+    XKc_Abrevetilde* = 0x00001EB4
+    XK_abrevetilde* = 0x00001EB5
+    XKc_Abrevebelowdot* = 0x00001EB6
+    XK_abrevebelowdot* = 0x00001EB7
+    XKc_Ebelowdot* = 0x00001EB8
+    XK_ebelowdot* = 0x00001EB9
+    XKc_Ehook* = 0x00001EBA
+    XK_ehook* = 0x00001EBB
+    XKc_Etilde* = 0x00001EBC
+    XK_etilde* = 0x00001EBD
+    XKc_Ecircumflexacute* = 0x00001EBE
+    XK_ecircumflexacute* = 0x00001EBF
+    XKc_Ecircumflexgrave* = 0x00001EC0
+    XK_ecircumflexgrave* = 0x00001EC1
+    XKc_Ecircumflexhook* = 0x00001EC2
+    XK_ecircumflexhook* = 0x00001EC3
+    XKc_Ecircumflextilde* = 0x00001EC4
+    XK_ecircumflextilde* = 0x00001EC5
+    XKc_Ecircumflexbelowdot* = 0x00001EC6
+    XK_ecircumflexbelowdot* = 0x00001EC7
+    XKc_Ihook* = 0x00001EC8
+    XK_ihook* = 0x00001EC9
+    XKc_Ibelowdot* = 0x00001ECA
+    XK_ibelowdot* = 0x00001ECB
+    XKc_Obelowdot* = 0x00001ECC
+    XK_obelowdot* = 0x00001ECD
+    XKc_Ohook* = 0x00001ECE
+    XK_ohook* = 0x00001ECF
+    XKc_Ocircumflexacute* = 0x00001ED0
+    XK_ocircumflexacute* = 0x00001ED1
+    XKc_Ocircumflexgrave* = 0x00001ED2
+    XK_ocircumflexgrave* = 0x00001ED3
+    XKc_Ocircumflexhook* = 0x00001ED4
+    XK_ocircumflexhook* = 0x00001ED5
+    XKc_Ocircumflextilde* = 0x00001ED6
+    XK_ocircumflextilde* = 0x00001ED7
+    XKc_Ocircumflexbelowdot* = 0x00001ED8
+    XK_ocircumflexbelowdot* = 0x00001ED9
+    XKc_Ohornacute* = 0x00001EDA
+    XK_ohornacute* = 0x00001EDB
+    XKc_Ohorngrave* = 0x00001EDC
+    XK_ohorngrave* = 0x00001EDD
+    XKc_Ohornhook* = 0x00001EDE
+    XK_ohornhook* = 0x00001EDF
+    XKc_Ohorntilde* = 0x00001EE0
+    XK_ohorntilde* = 0x00001EE1
+    XKc_Ohornbelowdot* = 0x00001EE2
+    XK_ohornbelowdot* = 0x00001EE3
+    XKc_Ubelowdot* = 0x00001EE4
+    XK_ubelowdot* = 0x00001EE5
+    XKc_Uhook* = 0x00001EE6
+    XK_uhook* = 0x00001EE7
+    XKc_Uhornacute* = 0x00001EE8
+    XK_uhornacute* = 0x00001EE9
+    XKc_Uhorngrave* = 0x00001EEA
+    XK_uhorngrave* = 0x00001EEB
+    XKc_Uhornhook* = 0x00001EEC
+    XK_uhornhook* = 0x00001EED
+    XKc_Uhorntilde* = 0x00001EEE
+    XK_uhorntilde* = 0x00001EEF
+    XKc_Uhornbelowdot* = 0x00001EF0
+    XK_uhornbelowdot* = 0x00001EF1
+    XKc_Ybelowdot* = 0x00001EF4
+    XK_ybelowdot* = 0x00001EF5
+    XKc_Yhook* = 0x00001EF6
+    XK_yhook* = 0x00001EF7
+    XKc_Ytilde* = 0x00001EF8
+    XK_ytilde* = 0x00001EF9
+    XKc_Ohorn* = 0x00001EFA     # U+01a0 
+    XK_ohorn* = 0x00001EFB      # U+01a1 
+    XKc_Uhorn* = 0x00001EFC     # U+01af 
+    XK_uhorn* = 0x00001EFD      # U+01b0 
+    XK_combining_tilde* = 0x00001E9F # U+0303 
+    XK_combining_grave* = 0x00001EF2 # U+0300 
+    XK_combining_acute* = 0x00001EF3 # U+0301 
+    XK_combining_hook* = 0x00001EFE # U+0309 
+    XK_combining_belowdot* = 0x00001EFF # U+0323 
+# XK_VIETNAMESE 
+
+when defined(XK_CURRENCY) or true: 
+  const
+    XK_EcuSign* = 0x000020A0
+    XK_ColonSign* = 0x000020A1
+    XK_CruzeiroSign* = 0x000020A2
+    XK_FFrancSign* = 0x000020A3
+    XK_LiraSign* = 0x000020A4
+    XK_MillSign* = 0x000020A5
+    XK_NairaSign* = 0x000020A6
+    XK_PesetaSign* = 0x000020A7
+    XK_RupeeSign* = 0x000020A8
+    XK_WonSign* = 0x000020A9
+    XK_NewSheqelSign* = 0x000020AA
+    XK_DongSign* = 0x000020AB
+    XK_EuroSign* = 0x000020AC
+# implementation
diff --git a/lib/base/x11/x.nim b/lib/wrappers/x11/x.nim
index aa6e7f821..aa6e7f821 100644
--- a/lib/base/x11/x.nim
+++ b/lib/wrappers/x11/x.nim
diff --git a/lib/base/x11/xatom.nim b/lib/wrappers/x11/xatom.nim
index b2e1dca91..b2e1dca91 100644
--- a/lib/base/x11/xatom.nim
+++ b/lib/wrappers/x11/xatom.nim
diff --git a/lib/base/x11/xcms.nim b/lib/wrappers/x11/xcms.nim
index 57aad6ae0..57aad6ae0 100644
--- a/lib/base/x11/xcms.nim
+++ b/lib/wrappers/x11/xcms.nim
diff --git a/lib/base/x11/xf86dga.nim b/lib/wrappers/x11/xf86dga.nim
index 376f11861..376f11861 100644
--- a/lib/base/x11/xf86dga.nim
+++ b/lib/wrappers/x11/xf86dga.nim
diff --git a/lib/base/x11/xf86vmode.nim b/lib/wrappers/x11/xf86vmode.nim
index 18a922cab..18a922cab 100644
--- a/lib/base/x11/xf86vmode.nim
+++ b/lib/wrappers/x11/xf86vmode.nim
diff --git a/lib/base/x11/xi.nim b/lib/wrappers/x11/xi.nim
index d1b9f7846..d1b9f7846 100644
--- a/lib/base/x11/xi.nim
+++ b/lib/wrappers/x11/xi.nim
diff --git a/lib/base/x11/xinerama.nim b/lib/wrappers/x11/xinerama.nim
index 96f5d7da3..96f5d7da3 100644
--- a/lib/base/x11/xinerama.nim
+++ b/lib/wrappers/x11/xinerama.nim
diff --git a/lib/base/x11/xkb.nim b/lib/wrappers/x11/xkb.nim
index f1b0448a8..f1b0448a8 100644
--- a/lib/base/x11/xkb.nim
+++ b/lib/wrappers/x11/xkb.nim
diff --git a/lib/base/x11/xkblib.nim b/lib/wrappers/x11/xkblib.nim
index 92d438a60..92d438a60 100644
--- a/lib/base/x11/xkblib.nim
+++ b/lib/wrappers/x11/xkblib.nim
diff --git a/lib/base/x11/xlib.nim b/lib/wrappers/x11/xlib.nim
index 84f9bbfc5..84f9bbfc5 100644
--- a/lib/base/x11/xlib.nim
+++ b/lib/wrappers/x11/xlib.nim
diff --git a/lib/base/x11/xrandr.nim b/lib/wrappers/x11/xrandr.nim
index ebc656260..ebc656260 100644
--- a/lib/base/x11/xrandr.nim
+++ b/lib/wrappers/x11/xrandr.nim
diff --git a/lib/base/x11/xrender.nim b/lib/wrappers/x11/xrender.nim
index c4f817607..c4f817607 100644
--- a/lib/base/x11/xrender.nim
+++ b/lib/wrappers/x11/xrender.nim
diff --git a/lib/base/x11/xresource.nim b/lib/wrappers/x11/xresource.nim
index ddb2a89c2..ddb2a89c2 100644
--- a/lib/base/x11/xresource.nim
+++ b/lib/wrappers/x11/xresource.nim
diff --git a/lib/base/x11/xshm.nim b/lib/wrappers/x11/xshm.nim
index e56bd87b1..e56bd87b1 100644
--- a/lib/base/x11/xshm.nim
+++ b/lib/wrappers/x11/xshm.nim
diff --git a/lib/base/x11/xutil.nim b/lib/wrappers/x11/xutil.nim
index 6cea7fba3..6cea7fba3 100644
--- a/lib/base/x11/xutil.nim
+++ b/lib/wrappers/x11/xutil.nim
diff --git a/lib/base/x11/xv.nim b/lib/wrappers/x11/xv.nim
index 45ab61418..45ab61418 100644
--- a/lib/base/x11/xv.nim
+++ b/lib/wrappers/x11/xv.nim
diff --git a/lib/base/x11/xvlib.nim b/lib/wrappers/x11/xvlib.nim
index 19fd0d000..19fd0d000 100644
--- a/lib/base/x11/xvlib.nim
+++ b/lib/wrappers/x11/xvlib.nim
diff --git a/lib/base/zip/libzip.nim b/lib/wrappers/zip/libzip.nim
index 2f8abc46c..2f8abc46c 100644
--- a/lib/base/zip/libzip.nim
+++ b/lib/wrappers/zip/libzip.nim
diff --git a/lib/base/zip/libzip_all.c b/lib/wrappers/zip/libzip_all.c
index 797374b29..797374b29 100644
--- a/lib/base/zip/libzip_all.c
+++ b/lib/wrappers/zip/libzip_all.c
diff --git a/lib/base/zip/zlib.nim b/lib/wrappers/zip/zlib.nim
index 9b49b9663..9b49b9663 100644
--- a/lib/base/zip/zlib.nim
+++ b/lib/wrappers/zip/zlib.nim
diff --git a/lib/base/zip/zzip.nim b/lib/wrappers/zip/zzip.nim
index a656322ee..a656322ee 100644
--- a/lib/base/zip/zzip.nim
+++ b/lib/wrappers/zip/zzip.nim