/* omalloc.h automatically generated by makeheader from om_Alloc.h */
#ifndef OMALLOC_H
#define OMALLOC_H
#endif
/*******************************************************************
*  File:    om_Alloc.h
*  Purpose: declaration of public routines for omalloc
*  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
*  Created: 11/99
*  Version: $Id$
*******************************************************************/
#ifndef OM_ALLOC_H
#define OM_ALLOC_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

/* stuff included from ./omConfig.h */

/* omConfig.h.  Generated automatically by configure.  */
/* -*-c++-*- */
/*******************************************************************
 *  File:    omConfig.h.in
 *  Purpose: configuration for omalloc
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_CONFIG_H
#define OM_CONFIG_H

/*******************************************************************
 * Defines which are set by configure
 ******************************************************************/
/* define if you provide an external config file to be included
   by omDefaultConfig.h */
#ifndef OM_HAVE_EXTERNAL_CONFIG_H
#define OM_HAVE_EXTERNAL_CONFIG_H 1
#endif
/* define if you can inline */
#ifndef OM_INLINE
#define OM_INLINE static inline
#endif
/* define for inline decl in headers */
#ifndef OM_INLINE_DECL
#define OM_INLINE_DECL static inline
#endif
/* define for inline implementation in Include*/
#ifndef OM_INLINE_IMPL
#define OM_INLINE_IMPL static inline
#endif
/* define for local inline */
#ifndef OM_INLINE_LOCAL
#define OM_INLINE_LOCAL static inline
#endif
/* defint to nothing if you do not understand const */
#ifndef const
/* #undef const */
#endif
/* define to the name of addr2line program, undef otherwise */
#ifndef OM_PROG_ADDR2LINE
#define OM_PROG_ADDR2LINE "addr2line"
#endif
/* define to the name of nm program, undef otherwise */
#ifndef OM_PROG_NM
/* #undef OM_PROG_NM */
#endif
/* define if you have popen */
#ifndef HAVE_POPEN
#define HAVE_POPEN 1
#endif
/* define if you have readlink */
#ifndef HAVE_READLINK
#define HAVE_READLINK 1
#endif
/* define if you have sbrk */
#ifndef HAVE_SBRK
#define HAVE_SBRK 1
#endif
/* define if you have getcwd */
#ifndef HAVE_GETCWD
#define HAVE_GETCWD 1
#endif
/* define if you have getwd */
#ifndef HAVE_GETWD
#define HAVE_GETWD 1
#endif
/* define if you have a working mmap */
#ifndef HAVE_WORKING_MMAP
#define HAVE_WORKING_MMAP 1
#endif
/* define if you have STDC_HEADERS */
#ifndef STDC_HEADERS
#define STDC_HEADERS 1
#endif
/* define if you have unistd.h */
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 1
#endif
/* define if you have fcntl.h */
#ifndef HAVE_FCNTL_H
#define HAVE_FCNTL_H
#endif
/* define if you have sys/mman.h */
#ifndef HAVE_SYS_MMAN_H
#define HAVE_SYS_MMAN_H
#endif
/* define if GET_RETURN_ADDR works */
#ifndef OM_GET_RETURN_ADDR_WORK
#define OM_GET_RETURN_ADDR_WORKS 1
#endif
/* define if GET_RETURN_ADDR works */
#ifndef OM_GET_BACKTRACE_WORK
#define OM_GET_BACKTRACE_WORKS 1
#endif
/* Define sizeof(long) */
#ifndef SIZEOF_LONG
#define SIZEOF_LONG 4
#endif
/* Define sizeof(double) */
#ifndef SIZEOF_DOUBLE
#define SIZEOF_DOUBLE 8
#endif
/* Define sizeof(size_t) */
#ifndef SIZEOF_SIZE_T
#define SIZEOF_SIZE_T 4
#endif
#ifndef SIZEOF_SYSTEM_PAGE
/* Define pagesize of your system */
#define SIZEOF_SYSTEM_PAGE 4096
#endif
#ifndef SIZEOF_OM_PAGE
/* size of page as we can use it */
#define SIZEOF_OM_PAGE SIZEOF_SYSTEM_PAGE
#endif
/* define if you want to use mmap for valloc */
#ifndef OM_HAVE_VALLOC_MMAP
#define OM_HAVE_VALLOC_MMAP 1
#endif
/* define if you want to use malloc-provided valloc */
#ifndef HAVE_VALLOC_MALLOC
/* #undef OM_HAVE_VALLOC_MALLOC */
#endif
#ifndef OM_MALLOC_PROVIDES_SIZEOF_ADDR
/* define if your malloc provides a working OM_MALLOC_SIZEOF_ADDR */
/* #undef OM_MALLOC_PROVIDES_SIZEOF_ADDR */
#endif
#ifndef OM_EMULATE_OMALLOC
/* define if you only want to emulate omalloc, but not actually use it */
/* #undef OM_EMULATE_OMALLOC */
#endif
#ifndef OM_ALIGN_8
/* define if you want your memory to be 8-aligned */
/* #undef OM_ALIGN_8 */
#endif
#ifndef OM_ALIGNMENT_NEEDS_WORK
/* define if you insist on AllocAligned returnes 8-aligned */
/* #undef OM_ALIGNMENT_NEEDS_WORK */
#endif
/* define if you want to have a dense distribution of bins */
#ifndef OM_HAVE_DENSE_BIN_DISTRIBUTION
/* #undef OM_HAVE_DENSE_BIN_DISTRIBUTION */
#endif
/* define to enable debug tracking */
#ifndef OM_HAVE_TRACK
#define OM_HAVE_TRACK 1
#endif
/* define to enable tracking of files/line numbers */
#ifndef OM_TRACK_FILE_LINE
#define OM_TRACK_FILE_LINE 1
#endif
/* define to enable tracking of return addresses */
#ifndef OM_TRACK_RETURN
/* #undef OM_TRACK_RETURN */
#endif
/* define to enable tracking of stack backtraces */
#ifndef OM_TRACK_BACKTRACE
/* #undef OM_TRACK_BACKTRACE */
#endif
/* define to enable tracking of custom value */
#ifndef OM_TRACK_CUSTOM
#define OM_TRACK_CUSTOM 1
#endif
/* define to enable internal debugging */
#ifndef OM_INTERNAL_DEBUG
/* #undef OM_INTERNAL_DEBUG */
#endif
/* define to -1/0/1/2/3 if you want omalloc to provide
   "underlying malloc"/no/normal/debug ANSI-C conforming
   malloc/calloc/realloc/free funcs */
#ifndef OM_PROVIDE_MALLOC
#define OM_PROVIDE_MALLOC 0
#endif
#endif /* OM_CONFIG_H  */
/* define if omalloc depends on "external" malloc functions like
   those provided by the system -- if this id defined, an application
   linking with omalloc needs to assure that a library containing malloc
   is linked, as well */
#ifndef OMALLOC_USES_MALLOC
#define OMALLOC_USES_MALLOC 1
#endif
/* stuff included from ./omDerivedConfig.h */

/*******************************************************************
 *  File:    omDerivedConfig.h.in
 *  Purpose: configuration which are derived from omConfig.h
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_DERIVED_CONFIG_H
#define OM_DERIVED_CONFIG_H

#ifndef SIZEOF_VOIDP
/* configure makes sure that SIZEOF_VOIDP == SIZEOF_LONG */
#define SIZEOF_VOIDP SIZEOF_LONG
#endif

/* SIZEOF_VOIDP == 8 || SIZEOF_VOIDP == 4 checked by configure */
#if SIZEOF_VOIDP == 8
#define LOG_SIZEOF_LONG  3
#define LOG_SIZEOF_VOIDP 3
#define LOG_BIT_SIZEOF_LONG 6
#else
#define LOG_SIZEOF_LONG  2
#define LOG_SIZEOF_VOIDP 2
#define LOG_BIT_SIZEOF_LONG 5
#endif

/* SIZEOF_SYSTEM_PAGE == 4096 || SIZEOF_SYSTEM_PAGE == 8192 checked by configure */
#if SIZEOF_SYSTEM_PAGE == 8192
#define LOG_BIT_SIZEOF_SYSTEM_PAGE 13
#else
#define LOG_BIT_SIZEOF_SYSTEM_PAGE 12
#endif

#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif

#ifndef BIT_SIZEOF_LONG
#define BIT_SIZEOF_LONG (CHAR_BIT << LOG_SIZEOF_LONG)
#endif

#ifdef OM_ALIGN_8
#define SIZEOF_OM_ALIGNMENT 8
#define SIZEOF_OM_ALIGNMENT_1 7
#define LOG_SIZEOF_OM_ALIGNMENT 3
#define SIZEOF_STRICT_ALIGNMENT 8
#else
#define SIZEOF_OM_ALIGNMENT 4
#define SIZEOF_OM_ALIGNMENT_1 3
#define LOG_SIZEOF_OM_ALIGNMENT 2
#ifdef OM_ALIGNMENT_NEEDS_WORK
#define SIZEOF_STRICT_ALIGNMENT 8
#else
#define SIZEOF_STRICT_ALIGNMENT 4
#endif
#endif

#define OM_ALIGN_SIZE(size) \
   ((((unsigned long) size) + SIZEOF_OM_ALIGNMENT_1) & (~SIZEOF_OM_ALIGNMENT_1))

#define OM_IS_ALIGNED(what) \
   ((((unsigned long) what) & SIZEOF_OM_ALIGNMENT_1) == 0)

#define OM_STRICT_ALIGN_SIZE(size)                                          \
   ((((size_t) (size)) + SIZEOF_STRICT_ALIGNMENT - 1) & (~ (SIZEOF_STRICT_ALIGNMENT - 1)))

#define OM_IS_STRICT_ALIGNED(what) \
   ((((unsigned long) what) & (SIZEOF_STRICT_ALIGNMENT -1)) == 0)

#if defined(OM_NDEBUG) && defined(OM_HAVE_TRACK)
#undef OM_HAVE_TRACK
#endif

/* define to enable assume */
#ifndef HAVE_OM_ASSUME
#if defined(OM_INTERNAL_DEBUG)
#define HAVE_OM_ASSUME
#endif
#endif

/* set to 0 to disable aso memory mamagent */
#ifndef HAVE_ASO
#define HAVE_ASO 1
#endif
#if defined(HAVE_ASO) && HAVE_ASO == 1
/* define to enable ASO debugging */
#undef ASO_DEBUG
#endif

#ifndef NULL
#define NULL ((void*)0)
#endif

#if !defined(OM_TRACK_FILE_LINE) && ! defined(OM_TRACK_RETURN)
#define OM_TRACK_FILE_LINE
#endif

/* The following macros save a lot of typing */
#ifdef OM_TRACK_FILE_LINE
#define OM_FL_DECL      const char* f, const int l
#define OM_FL_VAL       f, l
#define OM_FL           __FILE__,__LINE__
#define OM_FL_KOMMA     ,
#else
#define OM_FL_DECL
#define OM_FL_VAL
#define OM_FL
#define OM_FL_KOMMA
#endif

#define OM_CFL_DECL     char check OM_FL_KOMMA OM_FL_DECL
#define OM_CFL_VAL      check OM_FL_KOMMA OM_FL_VAL
#define OM_CFL          OM_CHECK OM_FL_KOMMA OM_FL

#define OM_TFL_DECL     char track OM_FL_KOMMA OM_FL_DECL
#define OM_TFL_VAL      track OM_FL_KOMMA OM_FL_VAL
#define OM_TFL          OM_TRACK OM_FL_KOMMA OM_FL

#define OM_CTFL_DECL    char check, char track OM_FL_KOMMA OM_FL_DECL
#define OM_CTFL_VAL     check,track OM_FL_KOMMA OM_FL_VAL
#define OM_CTFL         OM_CHECK,OM_TRACK OM_FL_KOMMA OM_FL

#ifdef OM_TRACK_RETURN
#define OM_FLR_DECL         OM_FL_DECL OM_FL_KOMMA const void* r
#define OM_FLR_VAL          OM_FL_VAL OM_FL_KOMMA r
#define OM_FLR              OM_FL OM_FL_KOMMA 0
#define OM_R_DEF            void* r; GET_RET_ADDR(r)
#ifdef OM_TRACK_FILE_LINE
#define OM_FLR_ARG(f,l,r)   f,l,r
#else
#define OM_FLR_ARG(f,l,r)   r
#endif

#else

#define OM_FLR_DECL OM_FL_DECL
#define OM_FLR_VAL  OM_FL_VAL
#define OM_FLR      OM_FL
#define OM_R_DEF    ((void)0)
#define OM_FLR_ARG(f,l,r)   f,l
#endif

#endif /* OM_DERIVED_CONFIG_H  */
/* stuff included from ./omError.h */

/*******************************************************************
 *  File:    omError.h
 *  Purpose: Error handling of omalloc
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_ERROR_H
#define OM_ERROR_H

#include <stdio.h>
/*******************************************************************
 *
 *  error codes
 *
 *******************************************************************/
enum omError_e
{
  omError_NoError = 0,
  omError_Unknown,
  omError_InternalBug,
  omError_MemoryCorrupted,
  omError_NullAddr,
  omError_InvalidRangeAddr,
  omError_FalseAddr,
  omError_FalseAddrOrMemoryCorrupted,
  omError_WrongSize,
  omError_FreedAddr,
  omError_FreedAddrOrMemoryCorrupted,
  omError_WrongBin,
  omError_UnknownBin,
  omError_NotBinAddr,
  omError_UnalignedAddr,
  omError_NullSizeAlloc,
  omError_ListCycleError,
  omError_SortedListError,
  omError_KeptAddrListCorrupted,
  omError_FreePattern,
  omError_BackPattern,
  omError_FrontPattern,
  omError_NotString,
  omError_StickyBin,
  omError_MaxError
};
typedef enum omError_e omError_t;

/* global variable holding last omError */
extern omError_t om_ErrorStatus;
/* globale variable holding last low-level omError */
extern omError_t om_InternalErrorStatus;
/* returns description of error */
const char* omError2String(omError_t error);
/* returns error as string */
const char* omError2Serror(omError_t error);
extern omError_t omReportError(omError_t error, omError_t report_error, OM_FLR_DECL,
                               const char* fmt, ...);

/* this is a dummy function and used as default for om_Opts.ErrorHook */
extern void omErrorBreak();

#ifndef OM_NDEBUG
extern void omPrintAddrInfo(FILE* fd, void* addr, const char* s);
#else
#define omPrintAddrInfo(fd, addr, s) fprintf(fd, "OM_NDEBUG: no addr info available\n")
#endif

/*BEGINPRIVATE*/

#ifndef OM_NDEBUG
extern int om_CallErrorHook;
#else
#define om_CallErrorHook 1
#endif

/*******************************************************************
 *
 * om_assume(x) -- a handy macro for assumptions
 *
 ******************************************************************/
#ifndef HAVE_OM_ASSUME

#define omAssume(x) ((void) 0)

#else /* ! HAVE_OM_ASSUME */

#define omAssume(x)                                             \
do                                                              \
{                                                               \
  if (! (x))                                                    \
  {                                                             \
    omReportError(omError_InternalBug, omError_InternalBug, OM_FLR, "omAssume violation");   \
  }                                                             \
}                                                               \
while (0)

#endif /* HAVE_OM_ASSUME */
/*ENDPRIVATE*/

#endif /* OM_LOCAL_H */
/* stuff included from ./omStructs.h */

/*******************************************************************
 *  File:    omStructs.h
 *  Purpose: declaration of structs and typedefs of omalloc
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_STRUCTS_H
#define OM_STRUCTS_H

struct omBin_s;
typedef struct omBin_s      omBin_t;
typedef omBin_t*            omBin;

struct omBinPage_s;
typedef struct omBinPage_s  omBinPage_t;
typedef omBinPage_t*        omBinPage;

struct omBinPageRegion_s;
typedef struct omBinPageRegion_s omBinPageRegion_t;
typedef omBinPageRegion_t* omBinPageRegion;

struct omOpts_s;
typedef struct omOpts_s omOpts_t;

struct omInfo_s;
typedef struct omInfo_s omInfo_t;

struct omSpecBin_s;
typedef struct omSpecBin_s omSpecBin_t;
typedef omSpecBin_t*        omSpecBin;

struct omRetInfo_s;
typedef struct omRetInfo_s omRetInfo_t;
typedef omRetInfo_t*        omRetInfo;

#endif /* OM_STRUCTS_H */
/* stuff included from ./omAllocDecl.h */

/*******************************************************************
 *  File:    omAllocDecl.h
 *  Purpose: declaration of Alloc routines
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_ALLOC_DECL_H
#define OM_ALLOC_DECL_H

#if defined(OM_NDEBUG) && defined(OMALLOC_H)
#if (SIZEOF_LONG == 8)
#define OM_T_FREE1
#define OM_T_FREE3
#define OM_T_STR
#define OM_T_ALLOC
#define OM_T_REALLOC
#undef OM_NDEBUG
#endif
#endif


#if (!defined(OM_EMULATE_OMALLOC) && !defined(OM_NDEBUG) && (defined(OM_CHECK) || (defined(OM_HAVE_TRACK) && defined(OM_TRACK)))) || defined(OM_T1)

/*******************************************************************
 *
 * Alloc/Free/Check for Debug
 *
 *******************************************************************/
#ifndef OM_CHECK
#define OM_CHECK    0
#endif
#ifndef OM_TRACK
#define OM_TRACK    0
#endif

#if OM_KEEP > 0
#define _OM_FKEEP OM_FKEEP
#else
#define _OM_FKEEP 0
#endif

#if !defined(OM_T_ALLOC)
#define omTypeAllocBin(type,addr,bin)           addr=(type)_omDebugAlloc(bin,OM_FBIN|_OM_FKEEP,OM_CTFL)
#define omTypeAlloc0Bin(type,addr,bin)          addr=(type)_omDebugAlloc(bin,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
#define omAllocBin(bin)                         _omDebugAlloc(bin,OM_FBIN|_OM_FKEEP,OM_CTFL)
#define omAlloc0Bin(bin)                        _omDebugAlloc(bin,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)

#define omTypeAlloc(type,addr,size)             addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|_OM_FKEEP,OM_CTFL)
#define omTypeAlloc0(type,addr,size)            addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
#define omAlloc(size)                           _omDebugAlloc((void*)(size),OM_FSIZE|_OM_FKEEP,OM_CTFL)
#define omAlloc0(size)                          _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)

#define omalloc(size)   _omDebugAlloc((void*)(size),OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omalloc0(size)  _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)

#else
#define omTypeAllocBin(type,addr,bin)           __omTypeAllocBin(type,addr,bin)
#define omTypeAlloc0Bin(type,addr,bin)          __omTypeAlloc0Bin(type,addr,bin)
#define omAllocBin(bin)                         _omAllocBin(bin)
#define omAlloc0Bin(bin)                        _omAlloc0Bin(bin)

#define omTypeAlloc(type,addr,size)             __omTypeAlloc(type,addr,size)
#define omTypeAlloc0(type,addr,size)            __omTypeAlloc0(type,addr,size)
#define omAlloc(size)                           _omAlloc(size)
#define omAlloc0(size)                          _omAlloc0(size)

#define omalloc(size)   _omalloc(size)
#define omalloc0(size)  _omalloc0(size)

#endif

#if !defined(OM_T_REALLOC)
#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            addr=(type)_omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|_OM_FKEEP,OM_CTFL)
#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           addr=(type)_omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)
#define omReallocBin(o_addr,o_bin,bin)                          _omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|_OM_FKEEP,OM_CTFL)
#define omRealloc0Bin(o_addr,o_bin,bin)                         _omDebugRealloc(o_addr,o_bin,bin,OM_FBIN|_OM_FKEEP,OM_FBIN|OM_FZERO|_OM_FKEEP,OM_CTFL)

#define omTypeReallocSize(o_addr,o_size,type,addr,size)         addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
#define omReallocSize(addr,o_size,size)                         _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
#define omRealloc0Size(addr,o_size,size)                        _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)

#define omTypeRealloc(o_addr,type,addr,size)                    addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|_OM_FKEEP,OM_CTFL)
#define omTypeRealloc0(o_addr,type,addr,size)                   addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO|_OM_FKEEP,OM_CTFL)
#define omRealloc(addr,size)                                    _omDebugRealloc(addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE,OM_CTFL)
#define omRealloc0(addr,size)                                   _omDebugRealloc(addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO,OM_CTFL)

#define omreallocSize(addr,o_size,size) _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omrealloc0Size(addr,o_size,size)_omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omrealloc(addr,size)            _omDebugRealloc(addr,NULL,(void*)(size),OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omrealloc0(addr,size)           _omDebugRealloc(addr,NULL,(void*)(size),OM_FSLOPPY|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FSLOPPY|OM_FALIGN|_OM_FKEEP,OM_CTFL)

#else
#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            __omTypeReallocBin(o_addr,o_bin,type,addr,bin)
#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           __omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)
#define omReallocBin(o_addr,o_bin,bin)                          _omReallocBin(o_addr,o_bin,bin)
#define omRealloc0Bin(o_addr,o_bin,bin)                         _omRealloc0Bin(o_addr,o_bin,bin)

#define omTypeReallocSize(o_addr,o_size,type,addr,size)         __omTypeReallocSize(o_addr,o_size,type,addr,size)
#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        __omTypeRealloc0Size(o_addr,o_size,type,addr,size)
#define omReallocSize(addr,o_size,size)                         _omReallocSize(addr,o_size,size)
#define omRealloc0Size(addr,o_size,size)                        _omRealloc0Size(addr,o_size,size)

#define omTypeRealloc(o_addr,type,addr,size)                    __omTypeRealloc(o_addr,type,addr,size)
#define omTypeRealloc0(o_addr,type,addr,size)                   __omTypeRealloc0(o_addr,type,addr,size)
#define omRealloc(addr,size)                                    _omRealloc(addr,size)
#define omRealloc0(addr,size)                                   _omRealloc0(addr,size)

#define omreallocSize(addr,o_size,size) _omreallocSize(addr,o_size,size)
#define omrealloc0Size(addr,o_size,size)_omrealloc0Size(addr,o_size,size)
#define omrealloc(addr,size)            _omrealloc(addr, size)
#define omrealloc0(addr,size)           _omrealloc0(addr, size)

#endif

#if !defined(OM_T_FREE1)
#define omFreeBinAddr(addr)     _omDebugFree(addr,NULL,OM_FBINADDR|_OM_FKEEP,OM_CFL)
#define omFreeBin(addr,bin)     _omDebugFree(addr,bin,OM_FBIN|_OM_FKEEP,OM_CFL)
#else
#define omFreeBinAddr(addr)     __omFreeBinAddr(addr)
#define omFreeBin(addr,bin)     __omFreeBinAddr(addr)
#endif

#if !defined(OM_T_FREE2)
#define omFreeSize(addr,size)   _omDebugFree(addr,(void*)(size),OM_FSIZE|_OM_FKEEP,OM_CFL)
#define omfreeSize(addr,size)   _omDebugFree(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY|_OM_FKEEP,OM_CFL)
#else
#define omFreeSize(addr,size)   __omFreeSize(addr,size)
#define omfreeSize(addr,size)   do {if (addr && size) omFreeSize(addr, size);} while (0)
#endif

#if !defined(OM_T_FREE3)
#define omFree(addr)            _omDebugFree(addr,0,0,OM_CFL)
#define omfree(addr)            _omDebugFree(addr,NULL,OM_FSLOPPY|_OM_FKEEP,OM_CFL)
#else
#define omFree(addr)            __omFree(addr)
#define omfree(addr)            do {if (addr) omFree(addr);} while (0)
#endif

#if !defined(OM_T_STR)
#define omStrDup(s)                             _omDebugStrDup(s,OM_TFL)
#define omMemDup(addr)                          _omDebugMemDup(addr,_OM_FKEEP,OM_CTFL)
#else
#define omStrDup(s)         _omStrDup(s)
#define omMemDup(s)         _omMemDup(s)
#endif

#define omDebugBinAddr(addr)                 _omDebugAddr(addr,NULL,OM_FBINADDR,OM_CFL)
#define omDebugAddrBin(addr, bin)            _omDebugAddr(addr,bin,OM_FBIN,OM_CFL)
#define omDebugBinAddrSize(addr, size)       _omDebugAddr(addr,(void*)(size),OM_FBINADDR|OM_FSIZE,OM_CFL)
#define omDebugAddrSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE,OM_CFL)
#define omDebugAddr(addr)                    _omDebugAddr(addr,NULL, 0, OM_CFL)
#define omdebugAddrSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY,OM_CFL)
#define omdebugAddr(addr)                    _omDebugAddr(addr,NULL, OM_FSLOPPY, OM_CFL)
#define omDebugBin(bin)                      _omDebugBin(bin,OM_CFL)
#define omDebugMemory()                      _omDebugMemory(OM_CFL)
#define omDebugIf(cond, statement)           do { if (cond) {statement;}} while (0)

#if OM_CHECK > 0
#define omCheckBinAddr      omDebugBinAddr
#define omCheckAddrBin      omDebugAddrBin
#define omCheckBinAddrSize  omDebugBinAddrSize
#define omCheckAddrSize     omDebugAddrSize
#define omCheckAddr         omDebugAddr
#define omcheckAddrSize     omdebugAddrSize
#define omcheckAddr         omdebugAddr
#define omCheckBin          omDebugBin
#define omCheckMemory       omDebugMemory
#define omCheckIf           omDebugIf
#endif /* OM_CHECK > 0 */


#ifdef OM_ALIGNMENT_NEEDS_WORK

#define omTypeAllocAligned(type,addr,size)             addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omTypeAlloc0Aligned(type,addr,size)            addr=(type)_omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omAllocAligned(size)                           _omDebugAlloc((void*)(size),OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omAlloc0Aligned(size)                          _omDebugAlloc((void*)(size),OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)

#define omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)         addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size)        addr=(type)_omDebugRealloc(o_addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omReallocAlignedSize(addr,o_size,size)                         _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omRealloc0AlignedSize(addr,o_size,size)                        _omDebugRealloc(addr,(void*)(o_size),(void*)(size),OM_FSIZE|_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)

#define omTypeReallocAligned(o_addr,type,addr,size)                    addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omTypeRealloc0Aligned(o_addr,type,addr,size)                   addr=(type)_omDebugRealloc(o_addr,NULL,(void*)(size),_OM_FKEEP,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omReallocAligned(addr,size)                                    _omDebugRealloc(addr,NULL,(void*)(size),0,OM_FSIZE|OM_FALIGN|_OM_FKEEP,OM_CTFL)
#define omRealloc0Aligned(addr,size)                                   _omDebugRealloc(addr,NULL,(void*)(size),0,OM_FSIZE|OM_FZERO|OM_FALIGN|_OM_FKEEP,OM_CTFL)

#define omMemDupAligned(addr)                       _omDebugMemDup(addr,OM_FALIGN|_OM_FKEEP,OM_CTFL)

#define omDebugBinAddrAligned(addr)                 _omDebugAddr(addr,NULL,OM_FBINADDR|OM_FALIGN,OM_CFL)
#define omDebugAddrAlignedBin(addr, bin)            _omDebugAddr(addr,bin,OM_FBIN|OM_FALIGN,OM_CFL)
#define omDebugAddrAlignedSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FALIGN,OM_CFL)
#define omDebugAddrAligned(addr)                    _omDebugAddr(addr,NULL, OM_FALIGN, OM_CFL)
#define omdebugAddrAlignedSize(addr,size)           _omDebugAddr(addr,(void*)(size),OM_FSIZE|OM_FSLOPPY|OM_FALIGN,OM_CFL)
#define omdebugAddrAligned(addr)                    _omDebugAddr(addr,NULL, OM_FSLOPPY|OM_FALIGN, OM_CFL)

#if OM_CHECK > 0
#define omCheckBinAddrAligned    omDebugBinAddrAligned
#define omCheckAddrAlignedBin    omDebugAddrAlignedBin
#define omCheckAddrAlignedSize   omDebugAddrAlignedSize
#define omCheckAddrAligned       omDebugAddrAligned
#define omcheckAddrAlignedSize   omdebugAddrAlignedSize
#define omcheckAddrAligned       omdebugAddrAligned
#endif
#endif /* OM_ALIGNMENT_NEEDS_WORK */

#elif !defined(OM_EMULATE_OMALLOC)
/*******************************************************************
 *
 * Alloc/Free -- the real thing
 *
 *******************************************************************/
#define omTypeAllocBin(type,addr,bin)           __omTypeAllocBin(type,addr,bin)
#define omTypeAlloc0Bin(type,addr,bin)          __omTypeAlloc0Bin(type,addr,bin)
#define omAllocBin(bin)                         _omAllocBin(bin)
#define omAlloc0Bin(bin)                        _omAlloc0Bin(bin)

#define omTypeAlloc(type,addr,size)             __omTypeAlloc(type,addr,size)
#define omTypeAlloc0(type,addr,size)            __omTypeAlloc0(type,addr,size)
#define omAlloc(size)                           _omAlloc(size)
#define omAlloc0(size)                          _omAlloc0(size)

#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            __omTypeReallocBin(o_addr,o_bin,type,addr,bin)
#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           __omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)
#define omReallocBin(o_addr,o_bin,bin)                          _omReallocBin(o_addr,o_bin,bin)
#define omRealloc0Bin(o_addr,o_bin,bin)                         _omRealloc0Bin(o_addr,o_bin,bin)

#define omTypeReallocSize(o_addr,o_size,type,addr,size)         __omTypeReallocSize(o_addr,o_size,type,addr,size)
#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        __omTypeRealloc0Size(o_addr,o_size,type,addr,size)
#define omReallocSize(addr,o_size,size)                         _omReallocSize(addr,o_size,size)
#define omRealloc0Size(addr,o_size,size)                        _omRealloc0Size(addr,o_size,size)

#define omTypeRealloc(o_addr,type,addr,size)                    __omTypeRealloc(o_addr,type,addr,size)
#define omTypeRealloc0(o_addr,type,addr,size)                   __omTypeRealloc0(o_addr,type,addr,size)
#define omRealloc(addr,size)                                    _omRealloc(addr,size)
#define omRealloc0(addr,size)                                   _omRealloc0(addr,size)

#define omalloc(size)   _omalloc(size)
#define omalloc0(size)  _omalloc0(size)

#define omreallocSize(addr,o_size,size) _omreallocSize(addr,o_size,size)
#define omrealloc0Size(addr,o_size,size)_omrealloc0Size(addr,o_size,size)
#define omrealloc(addr,size)            _omrealloc(addr, size)
#define omrealloc0(addr,size)           _omrealloc0(addr, size)

#define omfreeSize(addr,size)   do {if (addr && size) omFreeSize(addr, size);} while (0)
#define omfree(addr)            do {if (addr) omFree(addr);} while (0)

#ifdef OM_ALIGNMENT_NEEDS_WORK
#define omTypeAllocAligned(type,addr,size)      __omTypeAllocAligned(type,addr,size)
#define omTypeAlloc0Aligned(type,addr,size)     __omTypeAlloc0Aligned(type,addr,size)
#define omAllocAligned(size)                    _omAllocAligned(size)
#define omAlloc0Aligned(size)                   _omAlloc0Aligned(size)

#define omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)  __omTypeReallocAlignedSize(o_addr,o_size,type,addr,size)
#define omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size) __omTypeRealloc0AlignedSize(o_addr,o_size,type,addr,size)
#define omReallocAlignedSize(addr,o_size,size)                  _omReallocAlignedSize(addr,o_size,size)
#define omRealloc0AlignedSize(addr,o_size,size)                 _omRealloc0AlignedSize(addr,o_size,size)

#define omTypeReallocAligned(o_addr,type,addr,size)             __omTypeReallocAligned(o_addr,type,addr,size)
#define omTypeRealloc0Aligned(o_addr,type,addr,size)            __omTypeRealloc0Aligned(o_addr,type,addr,size)
#define omReallocAligned(addr,size)                             _omReallocAligned(addr,size)
#define omRealloc0Aligned(addr,size)                            _omRealloc0Aligned(addr,size)

#define omMemDupAligned(addr)                                   _omMemDupAligned(addr)
#endif  /* OM_ALIGNMENT_NEEDS_WORK */

#define omFreeBinAddr(addr)     __omFreeBinAddr(addr)
#define omFreeBin(addr,bin)     __omFreeBinAddr(addr)
#define omFreeSize(addr,size)   __omFreeSize(addr,size)
#define omFree(addr)            __omFree(addr)

#define omStrDup(s)         _omStrDup(s)
#define omMemDup(s)         _omMemDup(s)



#else /* OM_EMULATE_OMALLOC */
/*******************************************************************
 *
 * Emulation of omalloc's Alloc/Free interface
 *
 *******************************************************************/

#include <omalloc/omMalloc.h>

extern void* omEmulateCalloc(size_t size);
extern void* omEmulateRealloc0Size(void* o_addr, size_t o_size, size_t n_size);
extern void* omEmulateRealloc0(void* o_addr, size_t n_size);

#define omTypeAllocBin(type,addr,bin)           addr=(type) OM_MALLOC_MALLOC(bin->sizeW << LOG_SIZEOF_LONG)
#define omTypeAlloc0Bin(type,addr,bin)          addr=(type) omEmulateAlloc0(bin->sizeW << LOG_SIZEOF_LONG)
#define omAllocBin(bin)                         OM_MALLOC_MALLOC(bin->sizeW << LOG_SIZEOF_LONG)
#define omAlloc0Bin(bin)                        omEmulateAlloc0(bin->sizeW << LOG_SIZEOF_LONG)

#define omTypeAlloc(type,addr,size)             addr=(type) OM_MALLOC_MALLOC(size)
#define omTypeAlloc0(type,addr,size)            addr=(type) omEmulateAlloc0(size)
#define omAlloc(size)                           OM_MALLOC_MALLOC(size)
#define omAlloc0(size)                          omEmulateAlloc0(size)

#define omTypeReallocBin(o_addr,o_bin,type,addr,bin)            addr=(type)OM_MALLOC_REALLOC(o_addr,bin->sizeW << LOG_SIZEOF_LONG)
#define omTypeRealloc0Bin(o_addr,o_bin,type,addr,bin)           addr=(type)omEmulateRealloc0Size(o_addr,o_bin->sizeW << LOG_SIZEOF_LONG,bin->sizeW << LOG_SIZEOF_LONG)
#define omReallocBin(o_addr,o_bin,bin)                          OM_MALLOC_REALLOC(o_addr,bin->sizeW << LOG_SIZEOF_LONG)
#define omRealloc0Bin(o_addr,o_bin,bin)                         omEmulateRealloc0Size(o_addr,o_bin->sizeW << LOG_SIZEOF_LONG,bin->sizeW << LOG_SIZEOF_LONG)

#define omTypeReallocSize(o_addr,o_size,type,addr,size)         addr=(type)OM_MALLOC_REALLOC(o_addr,size)
#define omTypeRealloc0Size(o_addr,o_size,type,addr,size)        addr=(type)omEmulateRealloc0Size(o_addr,o_size,size)
#define omReallocSize(addr,o_size,size)                         OM_MALLOC_REALLOC(addr,size)
#define omRealloc0Size(addr,o_size,size)                        omEmulateRealloc0Size(addr,o_size,size)

#define omTypeRealloc(o_addr,type,addr,size)                    addr=(type)OM_MALLOC_REALLOC(o_addr,size)
#define omTypeRealloc0(o_addr,type,addr,size)                   addr=(type)omEmulateRealloc0(o_addr,size)
#define omRealloc(addr,size)                                    OM_MALLOC_REALLOC(addr,size)
#define omRealloc0(addr,size)                                   omEmulateRealloc0(addr,size)

#define omFreeBin(addr,bin)     OM_MALLOC_FREE(addr)
#define omFreeSize(addr,size)   OM_MALLOC_FREE(addr)
#define omFree(addr)            OM_MALLOC_FREE(addr)
#endif /* ! debug && ! the real thing */


/* define alignment stuff, if necessary */
#if !defined(omTypeAllocAligned)
#define omTypeAllocAligned      omTypeAlloc
#define omTypeAlloc0Aligned     omTypeAlloc0
#define omAllocAligned          omAlloc
#define omAlloc0Aligned         omAlloc0

#define omTypeReallocAlignedSize     omTypeReallocSize
#define omTypeRealloc0AlignedSize    omTypeRealloc0Size
#define omReallocAlignedSize         omReallocSize
#define omRealloc0AlignedSize        omRealloc0Size

#define omTypeReallocAligned         omTypeRealloc
#define omTypeRealloc0Aligned        omTypeRealloc0
#define omReallocAligned             omRealloc
#define omRealloc0Aligned            omRealloc0

#define omMemDupAligned     omMemDup
#endif /* !defined(omTypeAllocAligned) */

#if !defined(omDebugAddrAlignedBin)
#define omDebugBinAddrAligned   omDebugBinAddr
#define omDebugAddrAlignedBin   omDebugAddrBin
#define omDebugAddrAlignedSize  omDebugAddrSize
#define omDebugAddrAligned      omDebugAddr
#define omdebugAddrAlignedSize  omdebugAddrSize
#define omdebugAddrAligned      omdebugAddr
#endif /* !defined(omDebugAddrAlignedBin) */

#if !defined(omCheckAddrAlignedBin)
#define omCheckBinAddrAligned   omCheckBinAddr
#define omCheckAddrAlignedBin   omCheckAddrBin
#define omCheckAddrAlignedSize  omCheckAddrSize
#define omCheckAddrAligned      omCheckAddr
#define omcheckAddrAlignedSize  omcheckAddrSize
#define omcheckAddrAligned      omcheckAddr
#endif /* !defined(omCheckAddrAlignedBin) */

/* define debug stuff, if necessary */
#if !defined(omDebugAddrBin)
#define omDebugIf(cond, test)                    ((void) 0)
#define omDebugBinAddr(addr)                     ((void) 0)
#define omDebugAddrBin(addr,bin)                 ((void) 0)
#define omDebugBinAddrSize(addr,size)            ((void) 0)
#define omDebugAddrSize(addr,size)               ((void) 0)
#define omDebugAddr(addr)                        ((void) 0)
#define omdebugAddrSize(addr,size)               ((void) 0)
#define omdebugAddr(addr)                        ((void) 0)
#define omDebugBin(bin)                          ((void) 0)
#define omDebugMemory()                          ((void) 0)
#endif /* !defined(omDebugAddrBin) */

/* define check stuff, if necessary */
#if !defined(omCheckAddrBin)
#define omCheckIf(cond, test)                    ((void) 0)
#define omCheckBinAddr(addr)                     ((void) 0)
#define omCheckAddrBin(addr,bin)                 ((void) 0)
#define omCheckBinAddrSize(addr,size)            ((void) 0)
#define omCheckAddrSize(addr,size)               ((void) 0)
#define omCheckAddr(addr)                        ((void) 0)
#define omcheckAddrSize(addr,size)               ((void) 0)
#define omcheckAddr(addr)                        ((void) 0)
#define omCheckBin(bin)                          ((void) 0)
#define omCheckMemory()                          ((void) 0)
#endif /* !defined(omCheckAddrBin) */



#if !defined(OM_NDEBUG) && !defined(OM_EMULATE_MALLOC)
omError_t omTestAddrBin(void* addr, omBin bin, int check_level);
omError_t omTestBinAddr(void* addr, int check_level);
omError_t omTestBinAddrSize(void* addr, size_t size, int check_level);
omError_t omTestAddrSize(void* addr, size_t size, int check_level);
omError_t omTestAddr(void* addr, int check_level);
omError_t omtestAddrSize(void* addr, size_t size, int check_level);
omError_t omtestAddr(void* addr, int check_level);
omError_t omTestAddrAlignedBin(void* addr, omBin bin, int check_level);
omError_t omTestAddrAlignedSize(void* addr, size_t size, int check_level);
omError_t omTestAddrAligned(void* addr, int check_level);
omError_t omtestAddrAlignedSize(void* addr, size_t size, int check_level);
omError_t omtestAddrAligned(void* addr, int check_level);
omError_t omTestBin(omBin bin, int check_level);
omError_t omTestMemory(int check_level);
#define omTestIf(cond, statement)           do { if (cond) {statement;}} while (0)

#else

#define omTestIf(cond, test)                      ((void) 0)
#define omTestAddrBin(addr,bin,l)                 ((void) 0)
#define omTestBinAddr(addr,l)                     ((void) 0)
#define omTestBinAddrSize(addr,size,l)            ((void) 0)
#define omTestAddrSize(addr,size,l)               ((void) 0)
#define omTestAddr(addr,l)                        ((void) 0)
#define omtestAddrSize(addr,size,l)               ((void) 0)
#define omtestAddr(addr,l)                        ((void) 0)
#define omTestAddrAlignedBin(addr,bin,l)                 ((void) 0)
#define omTestAddrAlignedSize(addr,size,l)               ((void) 0)
#define omTestAddrAligned(addr,l)                        ((void) 0)
#define omtestAddrAlignedSize(addr,size,l)               ((void) 0)
#define omtestAddrAligned(addr,l)                        ((void) 0)
#define omTestBin(bin,l)                          ((void) 0)
#define omTestMemory(l)                           ((void) 0)

#endif

#endif /* OM_ALLOC_DECL_H */
/* stuff included from ./omInlineDecl.h */

/*******************************************************************
 *  File:    omInlineDecl.h
 *  Purpose: declarations of omalloc functions which could
 *           be inlined
 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_INLINE_DECL_H
#define OM_INLINE_DECL_H

OM_INLINE_DECL omBin omGetBinOfPage(omBinPage page);
OM_INLINE_DECL int _omIsBinPageAddr(const void* addr);

OM_INLINE_DECL void* _omAllocBin(omBin bin);
OM_INLINE_DECL void* _omAlloc0Bin(omBin bin);
OM_INLINE_DECL void* _omReallocBin(void* addr, omBin old_bin, omBin new_bin);
OM_INLINE_DECL void* _omRealloc0Bin(void* addr, omBin old_bin, omBin new_bin);

OM_INLINE_DECL void* _omAlloc(size_t size);
OM_INLINE_DECL void* _omAlloc0(size_t size);
OM_INLINE_DECL void* _omReallocSize(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omRealloc0Size(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omRealloc(void* addr, size_t size);
OM_INLINE_DECL void* _omRealloc0(void* addr, size_t size);

OM_INLINE_DECL void* _omalloc(size_t size);
OM_INLINE_DECL void* _omalloc0(size_t size);
OM_INLINE_DECL void* _omreallocSize(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omrealloc0Size(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omrealloc(void* addr, size_t size);
OM_INLINE_DECL void* _omrealloc0(void* addr, size_t size);

OM_INLINE_DECL char* _omStrDup(const char* s);
OM_INLINE_DECL void* _omMemDup(void* addr);

#ifdef OM_ALIGNMENT_NEEDS_WORK
OM_INLINE_DECL void* _omAllocAligned(size_t size);
OM_INLINE_DECL void* _omAlloc0Aligned(size_t size);
OM_INLINE_DECL void* _omReallocAlignedSize(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omRealloc0AlignedSize(void* addr, size_t old_size, size_t new_size);
OM_INLINE_DECL void* _omReallocAligned(void* addr, size_t size);
OM_INLINE_DECL void* _omRealloc0Aligned(void* addr, size_t size);
OM_INLINE_DECL void* _omMemDupAligned(void* addr);
#endif

#endif /* OM_INLINE_DECL_H */
/* stuff included from ./omBin.h */

/*******************************************************************
 *  File:    omBin.h
 *  Purpose: declaration of routines related to Bins
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_BIN_H
#define OM_BIN_H

#define omGetAlignedSpecBin(size) _omGetSpecBin(size, 1, 0)
#define omGetSpecBin(size) _omGetSpecBin(size, 0, 0)
omBin _omGetSpecBin(size_t size, int align, int track);

#define omUnGetSpecBin(bin_ptr) _omUnGetSpecBin(bin_ptr, 0)
#define omDeleteSpecBin(bin_ptr) _omUnGetSpecBin(bin_ptr, 1)
void _omUnGetSpecBin(omBin *bin, int force);
long omGetUsedBinBytes();

omBin omGetStickyBinOfBin(omBin bin);
void omMergeStickyBinIntoBin(omBin sticky_bin, omBin into_bin);

unsigned long omGetNewStickyBinTag(omBin bin);
void omSetStickyBinTag(omBin bin, unsigned long sticky);
void omUnSetStickyBinTag(omBin bin, unsigned long sticky);
void omDeleteStickyBinTag(omBin bin, unsigned long sticky);

unsigned long omGetNewStickyAllBinTag();
void omSetStickyAllBinTag(unsigned long sticky);
void omUnSetStickyAllBinTag(unsigned long sticky);
void omDeleteStickyAllBinTag(unsigned long sticky);

void omPrintBinStats(FILE* fd);
#define omIsStickyBin(bin) (bin->sticky >= SIZEOF_VOIDP)

/*BEGINPRIVATE*/
#ifndef OM_NDEBUG
int omIsKnownTopBin(omBin bin, int normal_bin);
#endif
#ifdef OM_HAVE_TRACK
#define omGetSpecTrackBin(size) _omGetSpecBin(size, 0, 1)
#endif

#define omIsStaticNormalBin(bin)                                            \
 ((unsigned long) bin >= ((unsigned long) &om_StaticBin[0]) &&              \
  (unsigned long) bin <= ((unsigned long) &om_StaticBin[OM_MAX_BIN_INDEX]))
#define omIsNormalBin(bin) omIsStaticNormalBin(bin) || omFindInGList(om_SpecBin, next, bin, bin) || omIsStickyBin(bin)
#define omIsSpecBin(bin) (!omIsStaticNormalBin(bin) && !omIsStickyBin(bin))

#ifdef OM_HAVE_TRACK
#define omIsStaticTrackBin(bin)                                                  \
 ((unsigned long) bin >= ((unsigned long) &om_StaticTrackBin[0]) &&              \
  (unsigned long) bin <= ((unsigned long) &om_StaticTrackBin[OM_MAX_BIN_INDEX]))
#define omIsTrackBin(bin) omIsStaticTrackBin(bin) || omFindInGList(om_SpecTrackBin, next, bin, bin)
#else
#define omIsKnownTopBin(bin, normal_bin)  1
#define omIsStaticTrackBin(bin) 0
#define omIsTrackBin(bin)       0
#endif
#define omIsStaticBin(bin) omIsStaticNormalBin(bin) || omIsStaticTrackBin(bin)
/*ENDPRIVATE*/

#endif /* OM_BIN_H */
/* stuff included from ./omMemOps.h */

/*******************************************************************
 *  File:    omMemOps.h
 *  Purpose: low-level Macros for memory operations
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/

#ifndef OM_MEM_OPS_H
#define OM_MEM_OPS_H

#ifdef DO_DEEP_PROFILE
extern void _omMemcpyW(long* p1, long* p2, long l);
#define omMemcpy_nwEVEN(p1, p2, l)    _omMemcpyW((long*) p1, (long*) p2, (long) l)
#define omMemcpy_nwODD(p1, p2, l)     _omMemcpyW((long*) p1, (long*) p2, (long) l)
#define omMemcpyW(p1, p2, l)          _omMemcpyW((long*) p1, (long*) p2, (long) l)

extern void _omMemaddW(long* p1, long* p2, long* p3, long l);
#define omMemaddW(p1, p2, p3, l)          _omMemaddW(p1, p2, p3, l)
#define omMemadd_nwODD(p1, p2, p3, l)     _omMemaddW(p1, p2, p3, l)
#define omMemadd_nwEVEN(p1, p2, p3, l)    _omMemaddW(p1, p2, p3, l)
#define omMemadd_nwONE(p1, p2, p3)        _omMemaddW(p1, p2, p3, 1)
#define omMemadd_nwTWO(p1, p2, p3)        _omMemaddW(p1, p2, p3, 2)

extern void _omMemsetW(long* p1, long w, long l);
#define omMemsetW(p1, w, l) _omMemsetW(p1, w, l)

#else /* ! DO_DEEP_PROFILE */

#define omMemcpyW(p1, p2, l)                    \
do                                              \
{                                               \
  long _i = l;                                  \
  long* _s1 = (long*) (p1);                       \
  const long* _s2 = (long*) (p2);                 \
                                                \
  for (;;)                                      \
  {                                             \
    *_s1 = *_s2;                                \
    _i--;                                       \
    if (_i == 0) break;                         \
    _s1++;                                      \
    _s2++;                                      \
  }                                             \
}                                               \
while(0)

#define omMemcpy_nwODD(p1, p2, l)               \
do                                              \
{                                               \
  long _i = (l) - 1;                              \
  long* _s1 = (long*) (p1);                       \
  const long* _s2 = (long*) (p2);                 \
                                                \
  *_s1++ = *_s2++;                              \
  for (;;)                                      \
  {                                             \
    *_s1++ = *_s2++;                            \
    *_s1++ = *_s2++;                            \
    _i -= 2;                                    \
    if (_i == 0) break;                         \
  }                                             \
}                                               \
while(0)

#define omMemcpy_nwEVEN(p1, p2, l)              \
do                                              \
{                                               \
  long _i = l;                                  \
  long* _s1 = (long*) (p1);                       \
  const long* _s2 = (long*) (p2);                 \
                                                \
  for (;;)                                      \
  {                                             \
    *_s1++ = *_s2++;                            \
    *_s1++ = *_s2++;                            \
    _i -= 2;                                    \
    if (_i == 0) break;                         \
  }                                             \
}                                               \
while(0)

#define omMemaddW(P1, P2, P3, L)                \
do                                              \
{                                               \
  unsigned long* _p1 = P1;                      \
  const unsigned long* _p2 = P2;                \
  const unsigned long* _p3 = P3;                \
  unsigned long l = L;                          \
                                                \
  do                                            \
  {                                             \
    *_p1++ = *_p2++ + *_p3++;                   \
    l--;                                        \
  }                                             \
  while(l);                                     \
}                                               \
while(0)

#define omMemadd_nwODD(P1, P2, P3, L)           \
do                                              \
{                                               \
  unsigned long* _p1 = P1;                      \
  const unsigned long* _p2 = P2;                \
  const unsigned long* _p3 = P3;                \
  unsigned long l = L;                          \
                                                \
 *_p1++ = *_p2++ + *_p3++;                      \
  l--;                                          \
                                                \
  do                                            \
  {                                             \
     *_p1++ = *_p2++ + *_p3++;                  \
     *_p1++ = *_p2++ + *_p3++;                  \
     l -=2;                                     \
  }                                             \
  while(l);                                     \
}                                               \
while(0)

#define omMemadd_nwEVEN(P1, P2, P3, L)          \
do                                              \
{                                               \
  unsigned long* _p1 = P1;                      \
  const unsigned long* _p2 = P2;                \
  const unsigned long* _p3 = P3;                \
  unsigned long l = L;                          \
                                                \
  do                                            \
  {                                             \
     *_p1++ = *_p2++ + *_p3++;                  \
     *_p1++ = *_p2++ + *_p3++;                  \
     l -=2;                                     \
  }                                             \
  while(l);                                     \
}                                               \
while(0)

#define omMemadd_nwONE(P1, P2, P3)              \
do                                              \
{                                               \
  unsigned long* _p1 = P1;                      \
  const unsigned long* _p2 = P2;                \
  const unsigned long* _p3 = P3;                \
                                                \
 *_p1 = *_p2 + *_p3;                            \
}                                               \
while(0)

#define omMemadd_nwTWO(P1, P2, P3)              \
do                                              \
{                                               \
  unsigned long* _p1 = P1;                      \
  const unsigned long* _p2 = P2;                \
  const unsigned long* _p3 = P3;                \
                                                \
 *_p1++ = *_p2++ + *_p3++;                      \
 *_p1 = *_p2 + *_p3;                            \
}                                               \
while(0)

#define omMemsetW(P1, W, L)                     \
do                                              \
{                                               \
  long* _p1 = (long*) (P1);                     \
  unsigned long _l = L;                         \
  unsigned long _w = W;                         \
  while(_l)                                     \
  {                                             \
    *_p1++ = _w;                                \
    _l--;                                       \
  }                                             \
}                                               \
while(0)

#endif /* DO_DEEP_PROFILE */

#endif /* OM_LIST_H */
/* stuff included from ./omList.h */

/*******************************************************************
 *  File:    omList.h
 *  Purpose: declaration of routines for operations on linked lists
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/

#ifndef OM_LIST_H
#define OM_LIST_H

#define OM_LIST_OFFSET(ptr, name_of_offset_field) \
  (ptr != NULL ? ((char*) &(ptr->name_of_offset_field)) - ((char*) ptr) : 0)

/********************************************************************
 *
 * Primitve routines -- don't use directly, use om macros, instead
 *
 ********************************************************************/
/* Returns the length of a memory list; assumes list has no cycles */
int _omListLength(void* list, int next);
/* Returns last non-NULL element of list; assumes list has no cycles */
void* _omListLast(void* list, int next);
/* Checks whether memory list has cycles: If yes, returns address of
 * first element of list which is contained at least twice in memory
 * list. If no, NULL is returned */
void* _omListHasCycle(void* list, int next);
/* returns addr, if addr is contained in memory list
 * 0, otherwise */
void* _omIsOnList(void* list, int next, void* addr);
/* Removes addr from list, if contained in it and returns new list */
void* _omRemoveFromList(void* list, int next, void* addr);
/*
 * The following cast list->long_field to a pointer to  unsigned long
 */
/* Find element with that value in list and return it, if found (else NULL) */
void* _omFindInList(void* list, int next, int long_field,
                    unsigned long what);
/*
 * The following assume that list is ordered increasingly w.r.t. long_field
 */
/* Finds element in sorted list */
void* _omFindInSortedList(void* list, int next, int long_field,
                          unsigned long what);
/* Remove element with that value from list and return new list */
void* _omRemoveFromSortedList(void* list,int next,int long_field,
                                  void* addr);
/* Inserts addr at the right place, returns list assumes addr != NULL */
void* _omInsertInSortedList(void* list, int next, int long_field,
                            void* addr);
#ifndef OM_NDEBUG
/* Check whether list is ok, i.e. whether addr of lists are aligned and in valid range */
omError_t _omCheckList(void* list, int next, int level, omError_t report, OM_FLR_DECL);
/* like above, but also check that sorting is ok */
omError_t _omCheckSortedList(void* list, int next, int long_field, int level, omError_t report, OM_FLR_DECL);
#endif

/********************************************************************
 *
 * The following routines assume that Next(list) == *((void**) list)
 *
 ********************************************************************/
#define omListLength(ptr) \
  _omListLength(ptr, 0)
#define omListLast(ptr) \
  _omListLast(ptr, 0)
#define omListHasCycle(ptr) \
  _omListHasCycle(ptr, 0)
#define omIsOnList(ptr, addr) \
  _omIsOnList(ptr, 0, addr)
#define omRemoveFromList(ptr, addr) \
  _omRemoveFromList(ptr, 0, addr)
#define omFindInList(ptr, what, value) \
  _omFindInList(ptr, 0, OM_LIST_OFFSET(ptr, what), (unsigned long) value)
#define omInsertInSortedList(ptr, what, addr) \
  _omInsertInSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), addr)
#define omFindInSortedList(ptr, what, value) \
  _omFindInSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), value)
#define omRemoveFromSortedList(ptr, what, addr) \
  _omRemoveFromSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), addr)
#ifndef OM_NDEBUG
#define omTestList(ptr, level) \
  _omCheckList(ptr, 0, level, omError_NoError, OM_FLR)
#define omCheckList(ptr, level, report, OM_FLR_VAL) \
  _omCheckList(ptr, 0, level, report, OM_FLR_VAL)
#define omCheckSortedList(ptr, what, level, report, OM_FLR_VAL) \
  _omCheckSortedList(ptr, 0, OM_LIST_OFFSET(ptr, what), level, report, OM_FLR_VAL)
#endif

/********************************************************************
 *
 * The following routines have name of next field as argument
 *
 ********************************************************************/
#define omGListLength(ptr, next) \
  _omListLength(ptr, OM_LIST_OFFSET(ptr, next))
#define omGListLast(ptr, next) \
  _omListLast(ptr, OM_LIST_OFFSET(ptr, next))
#define omGListHasCycle(ptr, next) \
  _omListHasCycle(ptr, OM_LIST_OFFSET(ptr, next))
#define omIsOnGList(ptr, next, addr) \
  _omIsOnList(ptr, OM_LIST_OFFSET(ptr, next), addr)
#define omRemoveFromGList(ptr, next, addr) \
  _omRemoveFromList(ptr, OM_LIST_OFFSET(ptr, next), addr)
#define omFindInGList(ptr, next, what, value) \
  _omFindInList(ptr, OM_LIST_OFFSET(ptr, next), OM_LIST_OFFSET(ptr, what), (unsigned long) value)
#define omInsertInSortedGList(ptr, next, what, addr) \
  _omInsertInSortedList(ptr, OM_LIST_OFFSET(ptr, next), OM_LIST_OFFSET(ptr, what), addr)
#define omFindInSortedGList(ptr, next, what, value) \
  _omFindInSortedList(ptr, OM_LIST_OFFSET(ptr, next),OM_LIST_OFFSET(ptr,what),value)
#define omRemoveFromSortedGList(ptr, next, what, addr) \
  _omRemoveFromSortedList(ptr, OM_LIST_OFFSET(addr,next),OM_LIST_OFFSET(addr,what),addr)
#ifndef OM_NDEBUG
#define omTestGList(ptr, next, level) \
 omCheckGList(ptr, next, level, omError_NoError, OM_FLR)
#define omCheckGList(ptr, next, level, report, OM_FLR_VAL) \
 _omCheckList(ptr, OM_LIST_OFFSET(ptr,next), level, report, OM_FLR_VAL)
#define omCheckSortedGList(ptr, next, what, level, report, OM_FLR_VAL) \
 _omCheckSortedList(ptr, OM_LIST_OFFSET(ptr,next), OM_LIST_OFFSET(ptr,what), level, report, OM_FLR_VAL)
#else
#define omTestGList(ptr, next, val) (omError_NoError)
#endif

#endif /* OM_LIST_H */
/* stuff included from ./omFindExec.h */

/*******************************************************************
 *  File:    omFindExec.h
 *  Purpose: declaration routines for getting Backtraces of stack
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_FIND_EXEC_H
#define OM_FIND_EXEC_H

/* determines absolute pathname of program prog, writes it into exec */
/* returns exec on succes, NULL on failure */
char* omFindExec(const char* prog, char* exec);

#endif /* OM_FINDEXEC_H */
/* stuff included from ./omGetBackTrace.h */

/*******************************************************************
 *  File:    omGetBackTrace.h
 *  Purpose: routines for getting Backtraces of stack
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_GET_BACKTRACE_H
#define OM_GET_BACKTRACE_H

#if defined(OM_GET_BACKTRACE_WORKS) && !defined(OM_NDEBUG) && !defined(__OPTIMIZE__)
void omInitGetBackTrace();
int omGetBackTrace(void** bt, int start, int max);
#else
#define omInitGetBackTrace() ((void)0)
#define omGetBackTrace(bt, s, max) (0)
#endif

#endif
/* stuff included from ./omRet2Info.h */

/*******************************************************************
 *  File:    omAddr2Info.h
 *  Purpose: translation of return addr to RetInfo
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_RET_2_INFO_H
#define OM_RET_2_INFO_H


struct omRetInfo_s
{
  void* addr;
  char  func[200]; /* if you change these numbers, alos change */
  char  file[200]; /* the fscanf statement in BackTrace_2_RetInfo */
  int   line;
};

/* print to fd array of max RetInfo's and use fmt as format string for one RetInfo.
   The following conversions are recognized:
    %i -- number of return addr
    %p -- address (in hex)
    %F -- function name with arguments (for C++, only)
    %N -- funtion name without arguments
    %f -- file
    %l -- line
    %L -- file:line
   return how many lines were printed */
#ifndef OM_NDEBUG
int omPrintRetInfo(omRetInfo info, int max, FILE *fd, const char* fmt);
/* translate array of max BackTrace addresses into array of max RetInfos
   return how many were translated */
int omBackTrace_2_RetInfo(void** bt, omRetInfo info, int max);

/* call with argv[0] to enable RetInfo translations */
void omInitRet_2_Info(const char* argv0);

int omPrintBackTrace(void** bt, int max, FILE* fd);
#define omPrintCurrentBackTrace(fd) omPrintCurrentBackTraceMax(fd, 1000)
int omPrintCurrentBackTraceMax(FILE* fd, int max);

int omFilterRetInfo_i(omRetInfo info, int max, int i);

#define omFilterRetInfo(info, max, cond)        \
do                                              \
{                                               \
  int _max = max;                               \
  int _i = max -1;                              \
  while (_i > 0)                                \
  {                                             \
    void* addr_i = info[_i].addr;               \
    char* file_i = info[_i].file;               \
    char* func_i = info[_i].func;               \
    int   line_i = info[_i].line;               \
                                                \
    if (cond)                                   \
      max = omFilterRetInfo_i(info, max, _i);   \
    _i--;                                       \
  }                                             \
}                                               \
while (0)


/*BEGINPRIVATE*/
int _omPrintBackTrace(void** bt, int max, FILE* fd , OM_FLR_DECL);
int _omPrintCurrentBackTrace(FILE* fd , OM_FLR_DECL);
/*ENDPRIVATE*/

#else /* OM_NDEBUG */
#define omPrintRetInfo(i, max, fd, fmt) ((void)0)
#define omBackTrace_2_RetInfo(bt, i, m) ((void)0)
#define omInitRet_2_Info(a)             ((void)0)
#define omPrintBackTrace(bt,max,fd)     ((void)0)
#define omPrintCurrentBackTrace(fd)     ((void)0)
#define omPrintCurrentBackTraceMax(fd,max) ((void)0)
#define omFilterRetInfo_i(info,max,i)   ((void)0)
#define omFilterRetInfo(info, max, cond)((void)0)
#endif /* ! OM_NDEBUG */

#endif /* OM_RET_2_INFO_H */
/* stuff included from ./omStats.h */

/*******************************************************************
 *  File:    omStats.h
 *  Purpose: declaration of statistics related stuff
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_STATS_H
#define OM_STATS_H

struct omInfo_s
{
  long MaxBytesSystem;      /* set in omUpdateInfo(), is more accurate with malloc support   */
  long CurrentBytesSystem;  /* set in omUpdateInfo(), is more accurate with malloc support */
  long MaxBytesSbrk;        /* always up-to-date, not very accurate, needs omInintInfo() */
  long CurrentBytesSbrk;    /* set in omUpdateInfo(), needs omInintInfo() */
  long MaxBytesMmap;        /* set in omUpdateInfo(), not very accurate */
  long CurrentBytesMmap;    /* set in omUpdateInfo(), not very accurate */
  long UsedBytes;           /* set in omUpdateInfo() */
  long AvailBytes;          /* set in omUpdateInfo() */
  long UsedBytesMalloc;     /* set in omUpdateInfo(), needs malloc support */
  long AvailBytesMalloc;    /* set in omUpdateInfo(), needs malloc support */
  long MaxBytesFromMalloc;      /* always kept up-to-date */
  long CurrentBytesFromMalloc;  /* always kept up-to-date */
  long MaxBytesFromValloc;      /* always kept up-to-date */
  long CurrentBytesFromValloc;  /* always kept up-to-date */
  long UsedBytesFromValloc; /* set in omUpdateInfo()  */
  long AvailBytesFromValloc;/* set in omUpdateInfo()  */
  long MaxPages;            /* always kept up-to-date */
  long UsedPages;           /* always kept up-to-date */
  long AvailPages;          /* always kept up-to-date */
  long MaxRegionsAlloc;     /* always kept up-to-date */
  long CurrentRegionsAlloc; /* always kept up-to-date */
};

/* returns a copy of omallinfo struct */
extern struct omInfo_s omGetInfo();
/* the struct itself which is always up-to-date */
/* use read-only */
extern struct omInfo_s om_Info;
/* update the global info struct */
extern void omUpdateInfo();
/* initialize such that sbrk can be measured */
extern void omInitInfo();
extern void omPrintStats(FILE* fd);
extern void omPrintInfo(FILE* fd);

/*BEGINPRIVATE*/
/* used internally to keep track of sbrk */
extern unsigned long om_SbrkInit;
/*ENDPRIVATE*/
#endif /* OM_STATS_H */
/* stuff included from ./omOpts.h */

/*******************************************************************
 *  File:    omOpts.h
 *  Purpose: declaration of options for omalloc
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_OPTS_H
#define OM_OPTS_H

/* Default values for these options are defined in omDefaultConfig.h */
struct omOpts_s
{
  int MinTrack;
  int MinCheck;
  int MaxTrack;
  int MaxCheck;
  int Keep;
  int HowToReportErrors;
  int MarkAsStatic;
  unsigned int PagesPerRegion;
  void (*OutOfMemoryFunc)();
  void (*MemoryLowFunc)();
  void (*ErrorHook)();
};
extern omOpts_t om_Opts;

#endif /* OM_OPTS_H */
/* stuff included from ./omBinPage.h */

/*******************************************************************
 *  File:    omBinPage.h
 *  Purpose: declaration of routines for primitve BinPage managment
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_BIN_PAGE_H
#define OM_BIN_PAGE_H

/***********************************************************************
 *
 * Macros for page manipulations
 *
 **********************************************************************/

#define omIsAddrPageAligned(addr) \
  (((long) (addr) & (SIZEOF_SYSTEM_PAGE -1)) == 0)

#define omGetPageOfAddr(addr) \
  ((void*) (((long)addr) & ~(SIZEOF_SYSTEM_PAGE -1)))

#define omGetBinPageOfAddr(addr) \
  ((omBinPage) ((long) (addr) & ~(SIZEOF_SYSTEM_PAGE -1)))

#define omIsAddrOnPage(addr, page) (omGetPageOfAddr(addr) == (void*) (page))

#define omAreAddrOnSamePage(a1, a2) \
  (omGetPageOfAddr(a1) == omGetPageOfAddr(a2))

/***********************************************************************
 *
 * Identifying whether an address is a BinPageAddr:
 *
 *******************************************************************/

/* Here is how it works (assume SIZEOF_LONG == 4, SIZEOF_SYSTEM_PAGE = 2^12):
   Let
   Addr: |    15               |  5       |    12        |
          PAGE_INDEX            PAGE_SHIFT PAGE_OFFSET

                                      PAGE_BASE

   om_PageIndicies is an array of bit-fields which is indexed by
                  PAGE_INDEX - om_MinBinPageIndex. Its maximal length
                  is 2^15. PAGE_SHIFT is used as index into the bit-field.
                  If it's value is 1, then addr is from omBinPage, else
                  not.

   om_MinPageIndex is minimal page index of registered BinPageAddr

   In other words: omIsBinPageAddr iff PAGE_INDEX >= om_MinBinPageIndex && PAGE_INDEX <=  om_MaxBinPageIndex
   && om_PageIndicies[PAGE_INDEX - om_MinPageIndex] & (1 << PAGE_SHIFT) */

extern unsigned long om_MaxBinPageIndex;
extern unsigned long om_MinBinPageIndex;
extern unsigned long *om_BinPageIndicies;

#define OM_SIZEOF_INDEX_PAGE (((unsigned long) SIZEOF_SYSTEM_PAGE) << LOG_BIT_SIZEOF_LONG)

#define omGetPageShiftOfAddr(addr) \
  ((((unsigned long) addr) & (OM_SIZEOF_INDEX_PAGE -1)) >> LOG_BIT_SIZEOF_SYSTEM_PAGE)

#define omGetPageIndexOfAddr(addr) \
  (((unsigned long) addr) >> (LOG_BIT_SIZEOF_LONG + LOG_BIT_SIZEOF_SYSTEM_PAGE))


#if defined(OM_INLINE) || defined(OM_INTERNAL_DEBUG)
#define omIsBinPageAddr(addr) _omIsBinPageAddr(addr)
#else
/* let's hope the compiler can eliminate common subexpressions well */      \
#define omIsBinPageAddr(addr)                                               \
  ((omGetPageIndexOfAddr(addr) >= om_MinBinPageIndex) &&                    \
   (omGetPageIndexOfAddr(addr) <= om_MaxBinPageIndex) &&                    \
   ((om_BinPageIndicies[omGetPageIndexOfAddr(addr) - om_MinBinPageIndex] &   \
     (((unsigned long) 1) << omGetPageShiftOfAddr(addr))) != 0))
#endif

/*BEGINPRIVATE*/
/*******************************************************************
 *
 * Alloc/Free of BinPages
 *
 *******************************************************************/
extern omBinPage omAllocBinPages(int how_many);
extern omBinPage omAllocBinPage();

extern void omFreeBinPages(omBinPage page, int how_many);
#define omFreeBinPage(addr) omFreeBinPages(addr, 1)
/*ENDPRIVATE*/

#endif /* OM_BIN_PAGE_H */
/* stuff included from ./omAllocSystem.h */

/*******************************************************************
 *  File:    omAllocSystem.h
 *  Purpose: declaration of routines for low-level alloc routines
 *           and page management
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_ALLOC_SYSTEM_H
#define OM_ALLOC_SYSTEM_H

size_t omSizeOfAddr(const void* addr);
size_t omSizeWOfAddr(void* addr);

size_t omSizeOfLargeAddr(void* addr);
#define omSizeWOfLargeAddr(addr) (omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG)

void* omAllocFromSystem(size_t size);
void* omReallocFromSystem(void* addr, size_t newsize);
void  omFreeToSystem(void* addr);

void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize);
void  omFreeSizeToSystem(void* addr, size_t size);

#define omVallocFromSystem(size) _omVallocFromSystem(size, 0)
void* _omVallocFromSystem(size_t size, int fail);
void omVfreeToSystem(void* page, size_t size);


#ifdef OM_MALLOC_PROVIDES_SIZEOF_ADDR
#define omAllocLarge(size)             omAllocFromSystem(OM_ALIGN_SIZE(size))
#define omReallocLarge(addr, new_size) omReallocSizeFromSystem(addr, omSizeOfLargeAddr(addr), OM_ALIGN_SIZE(new_size))
#define omFreeLarge(addr)              omFreeSizeToSystem(addr, omSizeOfLargeAddr(addr))
#else
void* omAllocLarge(size_t size);
void* omReallocLarge(void* old_addr, size_t new_size);
void  omFreeLarge(void* addr);
#endif
void* omRealloc0Large(void* old_addr, size_t new_size);
void* omAlloc0Large(size_t size);

#endif /* OM_ALLOC_SYSTEM_H */
/* stuff included from ./omTables.h */

#ifndef OM_TABLES_H
#define OM_TABLES_H
#define OM_MAX_BLOCK_SIZE 1016
#define OM_MAX_BIN_INDEX 23
#define OM_SIZEOF_UNIQUE_MAX_BLOCK_THRESHOLD 136
#endif /* OM_TABLES_H */
/* stuff included from ./omAllocPrivate.h */

/*******************************************************************
 *  File:    omAllocPrivate.h
 *  Purpose: declaration of "private" (but visible to the outside)
 *           routines for omalloc
 *  Author:  obachman (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_ALLOC_PRIVATE_H
#define OM_ALLOC_PRIVATE_H

/*******************************************************************
 *
 *  Definitions of structures we work with
 *
 *******************************************************************/
/* Need to define it here, has to be known to macros */
struct omBinPage_s
{
  long          used_blocks;    /* number of used blocks of this page */
  void*         current;        /* pointer to current freelist */
  omBinPage     next;           /* next/prev pointer of pages */
  omBinPage     prev;
  void*         bin_sticky;     /* bin this page belongs to with
                                   sticky tag of page hidden in ptr */
  omBinPageRegion region;       /* BinPageRegion of this page */
};

/* Change this appropriately, if you change omBinPage                 */
/* However, make sure that omBinPage is a multiple of SIZEOF_MAX_TYPE */
#define SIZEOF_OM_BIN_PAGE_HEADER (5*SIZEOF_VOIDP + SIZEOF_LONG)
#define SIZEOF_OM_BIN_PAGE (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE_HEADER)

/* keep all members of omBin_s a sizeof(long) type,
   otherwise list operations will fail */
struct omBin_s
{
  omBinPage     current_page;   /* page of current freelist */
  omBinPage     last_page;      /* pointer to last page of freelist */
  omBin         next;           /* sticky bins of the same size */
  size_t        sizeW;          /* size in words */
  long          max_blocks;     /* if > 0   # blocks in one page,
                                   if < 0   # pages for one block */
  unsigned long sticky;         /* sticky tag */
};

struct omSpecBin_s
{
  omSpecBin        next;       /* pointer to next bin */
  omBin            bin;        /* pointer to bin itself */
  long             max_blocks; /* max_blocks of bin*/
  long             ref;        /* ref count */
};

extern  omSpecBin   om_SpecBin;
extern  omBin       om_StickyBins;
extern  omBinPage_t om_ZeroPage[];
extern  omBin       om_Size2Bin[];

/*******************************************************************
 *
 *  Working with pages/bins
 *
 *******************************************************************/
#define omGetTopBinOfPage(page) \
  ((omBin) ( ((unsigned long) ((page)->bin_sticky)) & ~((unsigned long)SIZEOF_VOIDP - 1)))
#define omGetStickyOfPage(page) \
  (((unsigned long) ((page)->bin_sticky)) & ((unsigned long)SIZEOF_VOIDP-1))
#define omSetTopBinOfPage(page, bin) \
  (page)->bin_sticky= (void*)((unsigned long)bin + omGetStickyOfPage(page))
#define omSetStickyOfPage(page, sticky) \
  (page)->bin_sticky = (void*)(((unsigned long)sticky & ((unsigned long)SIZEOF_VOIDP-1)) + \
                                (unsigned long)omGetTopBinOfPage(page))
#define omSetTopBinAndStickyOfPage(page, bin, sticky) \
  (page)->bin_sticky= (void*)(((unsigned long)sticky & (SIZEOF_VOIDP-1)) \
                               + (unsigned long)bin)

#define omGetTopBinOfAddr(addr) \
  omGetTopBinOfPage(((omBinPage) omGetPageOfAddr(addr)))
#define omGetBinOfAddr(addr) omGetBinOfPage(omGetBinPageOfAddr(addr))

#ifndef OM_GENERATE_INC
extern omBin_t om_StaticBin[];
extern omBin om_Size2Bin[];
#ifdef OM_ALIGNMENT_NEEDS_WORK
extern omBin om_Size2AlignedBin[];
#endif

/*******************************************************************
 *
 *  SizeOfAddr
 *
 *******************************************************************/
#ifdef OM_INTERNAL_DEBUG
size_t omSizeOfBinAddr(void* addr);
#else
#define omSizeOfBinAddr(addr) _omSizeOfBinAddr(addr)
#endif

#define _omSizeOfBinAddr(addr)  ((omSizeWOfBinAddr(addr)) << LOG_SIZEOF_LONG)
#define omSizeWOfBinAddr(addr) ((omGetTopBinOfAddr(addr))->sizeW)

/*******************************************************************
 *
 *  lowest level alloc/free macros
 *
 *******************************************************************/
extern void* omAllocBinFromFullPage(omBin bin);
extern void  omFreeToPageFault(omBinPage page, void* addr);

/*******************************************************************/
/* Page                                                            */
#define __omTypeAllocFromNonEmptyPage(type, addr, page) \
do                                                      \
{                                                       \
  ((page)->used_blocks)++;                              \
  addr = (type)((page)->current);                       \
  (page)->current =  *((void**) (page)->current);       \
}                                                       \
while (0)

#define __omFreeToPage(addr, page)              \
do                                              \
{                                               \
  if ((page)->used_blocks > 0L)                 \
  {                                             \
    *((void**) (addr)) = (page)->current;       \
    ((page)->used_blocks)--;                    \
    (page)->current = (addr);                   \
  }                                             \
  else                                          \
  {                                             \
    omFreeToPageFault(page, addr);              \
  }                                             \
}                                               \
while (0)


/*******************************************************************/
/* Bin                                                             */
#define __omTypeAllocBin(type, addr, bin)                   \
do                                                          \
{                                                           \
  register omBinPage __om_page = (bin)->current_page;       \
  if (__om_page->current != NULL)                           \
    __omTypeAllocFromNonEmptyPage(type, addr, __om_page);   \
  else                                                      \
    addr = (type) omAllocBinFromFullPage(bin);              \
}                                                           \
while (0)

#define __omTypeAlloc0Bin(type, addr, bin)      \
do                                              \
{                                               \
  __omTypeAllocBin(type, addr, bin);            \
  omMemsetW(addr, 0, (bin)->sizeW);             \
}                                               \
while (0)


#define __omFreeBinAddr(addr)                                   \
do                                                              \
{                                                               \
  register void* __om_addr = (void*) (addr);                    \
  register omBinPage __om_page = omGetBinPageOfAddr(__om_addr); \
  __omFreeToPage(__om_addr, __om_page);                         \
}                                                               \
while (0)

#define __omTypeReallocBin(old_addr, old_bin, new_type, new_addr, new_bin)                              \
do                                                                                                      \
{                                                                                                       \
  if (old_bin != new_bin)                                                                               \
  {                                                                                                     \
    size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr));    \
    __omTypeAllocBin(new_type, new_addr, new_bin);                                                      \
    omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW));           \
    __omFreeBinAddr(old_addr);                                                                     \
  }                                                                                                     \
  else                                                                                                  \
  {                                                                                                     \
    new_addr = (new_type) old_addr;                                                                     \
  }                                                                                                     \
}                                                                                                       \
while (0)


#define __omTypeRealloc0Bin(old_addr, old_bin, new_type, new_addr, new_bin)                             \
do                                                                                                      \
{                                                                                                       \
  if (old_bin != new_bin)                                                                               \
  {                                                                                                     \
    size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr));    \
    __omTypeAllocBin(new_type, new_addr, new_bin);                                                      \
    omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW));           \
    if (new_bin->sizeW > old_sizeW)                                                                     \
       omMemsetW((void**)new_addr + old_sizeW, 0, new_bin->sizeW - old_sizeW);                          \
    __omFreeBinAddr(old_addr);                                                                     \
  }                                                                                                     \
  else                                                                                                  \
  {                                                                                                     \
    new_addr = (new_type) old_addr;                                                                     \
  }                                                                                                     \
}                                                                                                       \
while (0)

/*******************************************************************/
/* Size                                                            */
#define omSmallSize2Bin(size) om_Size2Bin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]

#define __omTypeAlloc(type, addr, size)         \
do                                              \
{                                               \
  size_t __size = size;                         \
  if (__size <= OM_MAX_BLOCK_SIZE)              \
  {                                             \
    omBin __om_bin = omSmallSize2Bin(__size);   \
    __omTypeAllocBin(type, addr, __om_bin);     \
  }                                             \
  else                                          \
  {                                             \
    addr = (type) omAllocLarge(__size);         \
  }                                             \
}                                               \
while(0)

#define __omTypeAlloc0(type, addr, size)        \
do                                              \
{                                               \
  size_t __size = size;                         \
  if (__size <= OM_MAX_BLOCK_SIZE)              \
  {                                             \
    omBin __om_bin = omSmallSize2Bin(__size);   \
    __omTypeAlloc0Bin(type, addr, __om_bin);    \
  }                                             \
  else                                          \
  {                                             \
    addr = (type) omAlloc0Large(__size);        \
  }                                             \
}                                               \
while (0)

#ifdef OM_ALIGNMENT_NEEDS_WORK
#define omSmallSize2AlignedBin(size) om_Size2AlignedBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]

#define __omTypeAllocAligned(type, addr, size)          \
do                                                      \
{                                                       \
  size_t __size = size;                                 \
  if (__size <= OM_MAX_BLOCK_SIZE)                      \
  {                                                     \
    omBin __om_bin = omSmallSize2AlignedBin(__size);    \
    __omTypeAllocBin(type, addr, __om_bin);             \
  }                                                     \
  else                                                  \
  {                                                     \
    addr = (type) omAllocLarge(__size);                 \
  }                                                     \
}                                                       \
while(0)

#define __omTypeAlloc0Aligned(type, addr, size)         \
do                                                      \
{                                                       \
  size_t __size = size;                                 \
  if (__size <= OM_MAX_BLOCK_SIZE)                      \
  {                                                     \
    omBin __om_bin = omSmallSize2AlignedBin(__size);    \
    __omTypeAlloc0Bin(type, addr, __om_bin);            \
  }                                                     \
  else                                                  \
  {                                                     \
    addr = (type) omAlloc0Large(__size);                \
  }                                                     \
}                                                       \
while (0)
#else
#define __omTypeAllocAligned    __omTypeAlloc
#define __omTypeAlloc0Aligned   __omTypeAlloc0
#endif /* OM_ALIGNMENT_NEEDS_WORK */

#define __omFreeSize(addr, size)                            \
do                                                          \
{                                                           \
  if ((size <= OM_MAX_BLOCK_SIZE) || omIsBinPageAddr(addr)) \
  {                                                         \
    __omFreeBinAddr(addr);                                  \
  }                                                         \
  else                                                      \
  {                                                         \
    omFreeLarge(addr);                                      \
  }                                                         \
}                                                           \
while (0)

#define __omFree(addr)                          \
do                                              \
{                                               \
  if (omIsBinPageAddr(addr))                    \
  {                                             \
    __omFreeBinAddr(addr);                         \
  }                                             \
  else                                          \
  {                                             \
    omFreeLarge(addr);                          \
  }                                             \
}                                               \
while (0)

void* omDoRealloc(void* old_addr, size_t new_size, int flags);

#define ___omTypeRealloc(old_addr, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags)    \
do                                                                                                  \
{                                                                                                   \
  size_t __new_size = new_size;                                                                     \
  if (__new_size <= OM_MAX_BLOCK_SIZE && omIsBinPageAddr(old_addr))                                 \
  {                                                                                                 \
    omBin __old_bin = omGetBinOfAddr(old_addr);                                                     \
    omBin __new_bin = SIZE_2_BIN(__new_size);                                                       \
    REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin);                                \
  }                                                                                                 \
  else                                                                                              \
  {                                                                                                 \
    new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags);                                 \
  }                                                                                                 \
}                                                                                                   \
while (0)

#define ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags)  \
do                                                                                                              \
{                                                                                                               \
  size_t __new_size = new_size;                                                                                 \
  if (__new_size <= OM_MAX_BLOCK_SIZE && old_size <= OM_MAX_BLOCK_SIZE)                                         \
  {                                                                                                             \
    omBin __old_bin = omGetBinOfAddr(old_addr);                                                                 \
    omBin __new_bin = SIZE_2_BIN(__new_size);                                                                   \
    REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin);                                            \
  }                                                                                                             \
  else                                                                                                          \
  {                                                                                                             \
    new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags);                                             \
  }                                                                                                             \
}                                                                                                               \
while (0)

#define __omTypeRealloc(old_addr, new_type, new_addr, new_size)                 \
  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
#define __omTypeRealloc0(old_addr, new_type, new_addr, new_size)                \
  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)
#define __omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size)     \
  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0)
#define __omTypeRealloc0Size(old_addr, old_size, new_type, new_addr, new_size)    \
  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1)

#ifdef OM_ALIGNMENT_NEEDS_WORK
#define __omTypeReallocAligned(old_addr, new_type, new_addr, new_size)                 \
  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
#define __omTypeRealloc0Aligned(old_addr, new_type, new_addr, new_size)                \
  ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
#define __omTypeReallocAlignedSize(old_addr, old_size, new_type, new_addr, new_size)     \
  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2)
#define __omTypeRealloc0AlignedSize(old_addr, old_size, new_type, new_addr, new_size)    \
  ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3)
#else
#define __omTypeReallocAligned      __omTypeRealloc
#define __omTypeRealloc0Aligned     __omTypeRealloc0
#define __omTypeReallocAlignedSize      __omTypeReallocSize
#define __omTypeRealloc0AlignedSize     __omTypeRealloc0Size
#endif

#endif /* OM_GENERATE_INC */
#endif /* OM_ALLOC_PRIVATE_H */
/* stuff included from ./omDebug.h */

/*******************************************************************
 *  File:    omDebug.h
 *  Purpose: declaration of common Debug/Check/Track stuff
 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
 *  Created: 7/00
 *  Version: $Id$
 *******************************************************************/
#ifndef OM_DEBUG_H
#define OM_DEBUG_H


#if defined(OM_NDEBUG) || ! defined(OM_HAVE_TRACK)
#define omIsTrackAddr(addr)             0
#define omIsTrackAddrPage(page)         0
#define omIsNormalBinPageAddr(addr)     omIsBinPageAddr(addr)
#define omIsBinAddrTrackAddr(addr)      0
#else
#define omIsTrackAddrBinPage(bin_page)  ((bin_page)->used_blocks < 0)
#define omIsBinAddrTrackAddr(addr)      omIsTrackAddrBinPage(omGetBinPageOfAddr(addr))
#define omIsTrackAddr(addr)             (omIsBinPageAddr(addr) && omIsBinAddrTrackAddr(addr))
#define omIsNormalBinPageAddr(addr)     (omIsBinPageAddr(addr) && !omIsBinAddrTrackAddr(addr))
#endif

#if defined(OM_NDEBUG)
#define omMarkAsStaticAddr(addr)    ((void)0)
#define omMarkMemoryAsStatic()      ((void)0)
#define omUnMarkAsStaticAddr()      ((void)0)
#define omUnMarkMemoryAsStatic()    ((void)0)
#define omFreeKeptAddr()            ((void)0)
#define omPrintUsedAddrs(fd,m)      ((void)0)
#define omPrintUsedTrackAddrs(fd,m) ((void)0)
#else
#define OM_FBIN     1           /* size_bin is bin */
#define OM_FSIZE    2           /* size_bin is size */
#define OM_FUSED    4           /* is in use, if set */
#define OM_FKEPT    8           /* had been freed, if set */
#define OM_FSTATIC  16          /* if set, considered to be static, i.e. never be freed */
#define OM_FZERO    32          /* for Alloc0 */
#define OM_FALIGN   64          /* for AllocAligned */
#define OM_FSLOPPY  128         /* be sloppy about arguments */
#define OM_FBINADDR 256         /* addr is bin addr */
#define OM_FKEEP    512         /* addr is never really freed */
/* maximal flag: OM_FBIN and OM_FSIZE can not be at the same time,
   and so can't OM_USED and OM_KEPT. Hence 1024 - BIN - USED*/
#define OM_FMAX     1024 - OM_FBIN - OM_FUSED
typedef unsigned short omTrackFlags_t;

void* _omDebugAlloc(void* size_bin, omTrackFlags_t flags, OM_CTFL_DECL);
void* _omDebugRealloc(void* old_addr, void* old_size_bin, void* new_size_bin,
                      omTrackFlags_t old_flags, omTrackFlags_t new_flags, OM_CTFL_DECL);
void  _omDebugFree(void* addr, void* size_bin, omTrackFlags_t flags, OM_CFL_DECL);
void* _omDebugMemDup(void* addr, omTrackFlags_t flags, OM_CTFL_DECL);
char* _omDebugStrDup(const char* addr, OM_TFL_DECL);

omError_t _omDebugBin(omBin bin, OM_CFL_DECL);
omError_t _omDebugMemory(OM_CFL_DECL);
omError_t _omDebugAddr(void* addr, void* bin_size, omTrackFlags_t flags, OM_CFL_DECL);

void omFreeKeptAddr();
void omPrintUsedAddrs(FILE* fd, int max_frames);
void omPrintUsedTrackAddrs(FILE* fd, int max_frames);

void omMarkAsStaticAddr(void* addr);
void omMarkMemoryAsStatic();
void omUnMarkAsStaticAddr(void* addr);
void omUnMarkMemoryAsStatic();
#endif /* ! OM_NDEBUG */


#ifdef OM_TRACK_CUSTOM
#ifdef OM_NDEBUG
#define omSetCustomOfAddr(addr,value) ((void)0)
#define omGetCustomOfAddr(addr) ((void*)0)
#define omSetCustomOfTrackAddr(addr,value) ((void)0)
#define omGetCustomOfTrackAddr(addr) ((void*)0)
#else
void omSetCustomOfTrackAddr(void* addr, void* value);
void* omGetCustomOfTrackAddr(void* addr);
#define omSetCustomOfAddr(addr,value) \
  do{if (omIsTrackAddr(addr)) omSetCustomOfTrackAddr(addr,value);}while(0)
#define omGetCustomOfAddr(addr) \
  (omIsTrackAddr(addr) ? omGetCustomOfTrackAddr(addr) : NULL)
#endif /* OM_NDEBUG */
#endif /* OM_TRACK_CUSTOM */

/*BEGINPRIVATE*/

#if defined(OM_NDEBUG) || ! defined(OM_HAVE_TRACK)
#define omGetUsedBlocksOfPage(page)     (page->used_blocks)
#else
#define omGetUsedBlocksOfPage(page)     ((long)(page->used_blocks & ~(((unsigned long) 1) << (BIT_SIZEOF_LONG -1))))
#endif

#ifndef OM_NDEBUG
extern void* om_KeptAddr;
extern void* om_LastKeptAddr;
extern unsigned long om_MaxAddr;
extern unsigned long om_MinAddr;
extern void* om_AlwaysKeptAddrs;

void omFreeKeptAddrFromBin(omBin bin);
/***********************************************************************
 *
 * omDebugCheck.c
 *
 **********************************************************************/
omError_t omCheckPtr(const void* ptr, omError_t report, OM_FLR_DECL);
omError_t _omCheckAddr(void* addr, void* size_bin, omTrackFlags_t flags, char check,
                       omError_t report, OM_FLR_DECL);
omError_t omDoCheckBinAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
                           omError_t report, OM_FLR_DECL);
omError_t _omCheckBin(omBin bin, int normal_bin, char check,  omError_t report, OM_FLR_DECL);
omError_t _omCheckMemory(char check,  omError_t report, OM_FLR_DECL);
omError_t omReportAddrError(omError_t error, omError_t report, void* addr,
                            void* bin_size, omTrackFlags_t flags,
                            OM_FLR_DECL, const char* fmt, ...);
omError_t omDoCheckBin(omBin bin, int normal_bin, char level,
                       omError_t report, OM_FLR_DECL);
void omIterateTroughAddrs(int normal, int track, void (*CallBackUsed)(void*), void (*CallBackFree)(void*));
void omIterateTroughBinAddrs(omBin bin, void (*CallBackUsed)(void*), void (*CallBackFree)(void*));
omError_t omDoCheckAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
                        omError_t report, OM_FLR_DECL);
int omIsInKeptAddrList(void* addr);

/***********************************************************************
 *
 * omDebugTrack.c
 *
 **********************************************************************/
#ifdef OM_HAVE_TRACK
extern omBin_t om_StaticTrackBin[];
extern omBin om_Size2TrackBin[];
#define omSmallSize2TrackBin(size)      om_Size2TrackBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT]
extern omBinPage om_JustFreedPage;
extern void omFreeTrackAddr(void* addr);
extern size_t omOutSizeOfTrackAddr(void* addr);
extern omSpecBin om_SpecTrackBin;

void* omAllocTrackAddr(void* bin_size, omTrackFlags_t flags, char track, OM_FLR_DECL);
void* omMarkAsFreeTrackAddr(void* addr, int keep, omTrackFlags_t *flags, OM_FLR_DECL);
omError_t omCheckTrackAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level,
                           omError_t report_error, OM_FLR_DECL);
void omPrintTrackAddrInfo(FILE* fd, void* addr, int max_frames);
omBin omGetOrigSpecBinOfTrackAddr(void* addr);
size_t omOutSizeOfTrackAddr(void* addr);
extern int omIsStaticTrackAddr(void* addr);
#define omSetTrackOfUsedBlocks(ub)      (ub |= (((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
#define omUnsetTrackOfUsedBlocks(ub)    (ub &= ~(((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
#define omIsSetTrackOfUsedBlocks(ub)    (ub & (((unsigned long) 1) << (BIT_SIZEOF_LONG -1)))
#else
#define omIsStaticTrackAddr(addr)   0
#endif
void* omAddr_2_OutAddr(void* addr);

/***********************************************************************
 *
 * omBinPage.c
 *
 **********************************************************************/
int omIsKnownMemoryRegion(omBinPageRegion region);
omError_t omCheckBinPageRegion(omBinPageRegion region, int level, omError_t report, OM_FLR_DECL);
omError_t omCheckBinPageRegions(int level, omError_t report, OM_FLR_DECL);
omBinPageRegion omFindRegionOfAddr(void* addr);
int omIsAddrOnFreeBinPage(void* addr);

/***********************************************************************
 *
 * Some Handy Macros
 *
 **********************************************************************/
#define omCheckReturn(cond) \
  do {omError_t _status = cond; if (_status) return _status;} while (0)
#define omCheckReturnError(cond, error) \
  do {if (cond) return omReportError(error, report, OM_FLR_VAL, "");} while (0)
#define omCheckReturnCorrupted(cond) \
  omCheckReturnError(cond, omError_MemoryCorrupted)
#define omAddrCheckReturn(cond)                                               \
do                                                                            \
{                                                                             \
  omError_t _status = cond;                                                   \
  if (_status && (_status != omError_MaxError))                               \
  {                                                                           \
    _omPrintAddrInfo(stderr, _status, addr, bin_size, flags, 10, "  occured for"); \
    return _status;                                                           \
  }                                                                           \
} while (0)
#define omAddrCheckReturnError(cond, error) \
  do {if (cond) return omReportAddrError(error, report, addr, bin_size, flags, OM_FLR_VAL, "");} while (0)
#define omAddrCheckReturnCorrupted(cond) \
  omAddrCheckReturnError(cond, omError_MemoryCorrupted)

#else
#define omFreeKeptAddrFromBin(bin) ((void)0)
#endif /* ! OM_NDEBUG */
/*ENDPRIVATE*/

#endif /* OM_DEBUG_H */
/* stuff included from ./omInline.h */

/*******************************************************************
 *  File:    omInline.c
 *  Purpose: implementation of omalloc functions which could
 *           be inlined
 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/
#if defined(OM_INLINE) || defined(OM_ALLOC_C)

#ifndef OM_INLINE_H
#define OM_INLINE_H

OM_INLINE_IMPL omBin omGetBinOfPage(omBinPage page)
{
  unsigned long sticky = omGetStickyOfPage(page);
  omBin bin = omGetTopBinOfPage(page);

  if (! omIsStickyBin(bin))
  {
    while (bin->sticky != sticky && bin->next != NULL)
    {
      bin = bin->next;
    }
  }
  return bin;
}

OM_INLINE_IMPL int _omIsBinPageAddr(const void* addr)
{
  unsigned long index = omGetPageIndexOfAddr(addr);
  if (index >= om_MinBinPageIndex && index <= om_MaxBinPageIndex)
  {
    unsigned long shift = omGetPageShiftOfAddr(addr);
    return ((om_BinPageIndicies[index - om_MinBinPageIndex] & (((unsigned long) 1) << shift)) != 0L);
  }
  return 0;
}

OM_INLINE_IMPL void* _omAllocBin(omBin bin)
{
  void* addr;
  __omTypeAllocBin(void*, addr, bin);
  return addr;
}
OM_INLINE_IMPL void* _omAlloc0Bin(omBin bin)
{
  void* addr;
  __omTypeAlloc0Bin(void*, addr, bin);
  return addr;
}
OM_INLINE_IMPL void* _omReallocBin(void* addr, omBin old_bin, omBin new_bin)
{
  void* new_addr;
  __omTypeReallocBin(addr, old_bin, void*, new_addr, new_bin);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc0Bin(void* addr, omBin old_bin, omBin new_bin)
{
  void* new_addr;
  __omTypeRealloc0Bin(addr, old_bin, void*, new_addr, new_bin);
  return new_addr;
}


OM_INLINE_IMPL void* _omAlloc(size_t size)
{
  void* addr;
  __omTypeAlloc(void*, addr, size);
  return addr;
}
OM_INLINE_IMPL void* _omAlloc0(size_t size)
{
  void* addr;
  __omTypeAlloc0(void*, addr, size);
  return addr;
}
OM_INLINE_IMPL void* _omReallocSize(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;
  __omTypeReallocSize(addr, old_size, void*, new_addr, new_size);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc0Size(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;
  __omTypeRealloc0Size(addr, old_size, void*, new_addr, new_size);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc(void* addr, size_t size)
{
  void* new_addr;
  __omTypeRealloc(addr, void*, new_addr, size);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc0(void* addr, size_t size)
{
  void* new_addr;
  __omTypeRealloc0(addr, void*, new_addr, size);
  return new_addr;
}

#ifdef OM_ALIGNMENT_NEEDS_WORK
OM_INLINE_IMPL void* _omAllocAligned(size_t size)
{
  void* addr;
  __omTypeAllocAligned(void*, addr, size);
  return addr;
}
OM_INLINE_IMPL void* _omAlloc0Aligned(size_t size)
{
  void* addr;
  __omTypeAlloc0Aligned(void*, addr, size);
  return addr;
}
OM_INLINE_IMPL void* _omReallocAlignedSize(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;
  __omTypeReallocAlignedSize(addr, old_size, void*, new_addr, new_size);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc0AlignedSize(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;
  __omTypeRealloc0AlignedSize(addr, old_size, void*, new_addr, new_size);
  return new_addr;
}
OM_INLINE_IMPL void* _omReallocAligned(void* addr, size_t size)
{
  void* new_addr;
  __omTypeReallocAligned(addr, void*, new_addr, size);
  return new_addr;
}
OM_INLINE_IMPL void* _omRealloc0Aligned(void* addr, size_t size)
{
  void* new_addr;
  __omTypeRealloc0Aligned(addr, void*, new_addr, size);
  return new_addr;
}

OM_INLINE_IMPL void* _omMemDupAligned(void* addr)
{
  void* r;
  size_t sizeW = omSizeWOfAddr(addr);
  __omTypeAllocAligned(void*, r, sizeW << LOG_SIZEOF_LONG);
  omMemcpyW(r, addr, sizeW);
  return r;
}

#endif /* OM_ALIGNMENT_NEEDS_WORK */

OM_INLINE_IMPL char* _omStrDup(const char* s)
{
  void* r;
  size_t i=(size_t)0;

  while (s[i]) i++;
  i++;
  __omTypeAlloc(void*, r, i);
  memcpy(r, (void*) s, i);
  return (char*) r;
}

OM_INLINE_IMPL void* _omMemDup(void* addr)
{
  void* r;
  if (omIsNormalBinPageAddr(addr))
  {
    omBin bin = omGetTopBinOfAddr(addr);
    __omTypeAllocBin(void*, r, bin);
    omMemcpyW(r, addr, bin->sizeW);
  }
  else
  {
    size_t size = omSizeWOfAddr(addr);
    __omTypeAlloc(void*, r, size << LOG_SIZEOF_LONG);
    omMemcpyW(r, addr, size);
  }
  return r;
}

OM_INLINE_IMPL void* _omalloc(size_t size)
{
  void* addr;
  if (! size) size = (size_t)1;
  __omTypeAllocAligned(void*, addr,size);
  return addr;
}

OM_INLINE_IMPL void* _omalloc0(size_t size)
{
  void* addr;
  if (! size) size = (size_t)1;
  __omTypeAlloc0Aligned(void*,addr, size);
  return addr;
}

OM_INLINE_IMPL void* _omreallocSize(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;

  if (!new_size) new_size = (size_t)1;
  if (addr != NULL)
  {
    __omTypeReallocAlignedSize(addr, old_size, void* , new_addr, new_size);
  }
  else
  {
    __omTypeAllocAligned(void* , new_addr, new_size);
  }
  return new_addr;
}

OM_INLINE_IMPL void* _omrealloc0Size(void* addr, size_t old_size, size_t new_size)
{
  void* new_addr;

  if (!new_size) new_size = (size_t)1;
  if (addr != NULL && old_size > ((size_t)0))
  {
    __omTypeRealloc0AlignedSize(addr, old_size, void* , new_addr, new_size);
  }
  else
  {
    __omTypeAlloc0(void* , new_addr, new_size);
  }
  return new_addr;
}

OM_INLINE_IMPL void* _omrealloc(void* addr, size_t size)
{
  void* new_addr;

  if (!size) size = (size_t)1;
  if (addr != NULL)
  {
    __omTypeReallocAligned(addr, void* , new_addr, size);
  }
  else
  {
    __omTypeAlloc(void* , new_addr, size);
  }
  return new_addr;
}

OM_INLINE_IMPL void* _omrealloc0(void* addr, size_t size)
{
  void* new_addr;

  if (!size) size = (size_t)1;
  if (addr != NULL)
  {
    __omTypeRealloc0Aligned(addr, void* , new_addr, size);
  }
  else
  {
    __omTypeAlloc0(void* , new_addr, size);
  }
  return new_addr;
}
#endif /* OM_INLINE_H */

#endif /* defined(OM_INLINE) || defined(OM_ALLOC_C) */
/* stuff included from ./omAllocFunc.h */

/*******************************************************************
 *  File:    omAllocFunc.h
 *  Purpose: declaration of ANSI-C conforming malloc functions
 *           which are sure to be functions, which start with the om prefix,
 *           and end with the Func suffix.
 *  Author:  obachman@mathematik.uni-kl.de (Olaf Bachmann)
 *  Created: 11/99
 *  Version: $Id$
 *******************************************************************/

void* omCallocFunc(size_t nmemb, size_t size);
void* omMallocFunc(size_t size);
void omFreeFunc(void* addr);
void* omVallocFunc(size_t size);
#if defined(sgi)
void* omMemalignFunc(size_t size_1, size_t size_2);
#else
#if (defined(__sun) && (defined(__sparc) || defined(__i386) || defined(__x86_64)) || defined(__CYGWIN__))
extern void* omMemalignFunc(size_t, size_t);
#else
void* omMemalignFunc(void* alignment, size_t size);
#endif
#endif
void* omReallocFunc(void* old_addr, size_t new_size);
char* omStrdupFunc(const char* addr);
void* omReallocSizeFunc(void* old_addr, size_t old_size, size_t new_size);
void omFreeSizeFunc(void* addr, size_t size);

#ifdef __cplusplus
}
#endif

#endif /* OM_ALLOC_H */
