Files
ldc/tk/mem.h
Alexey Prokhin caad8cde58 Squashed 'dmd2/' content from commit 10017d5
git-subtree-dir: dmd2
git-subtree-split: 10017d50eaaff4ecdc37a0153b6c37ea0b004c81
2012-04-05 11:10:48 +04:00

272 lines
8.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*_ mem.h */
/* Copyright 1986-1997 by Walter Bright */
/* All Rights Reserved */
/* Written by Walter Bright */
#ifndef MEM_H
#define MEM_H 1
#if __SC__
#pragma once
#endif
/*
* Memory management routines.
*
* Compiling:
*
* #define MEM_DEBUG 1 when compiling to enable extended debugging
* features.
*
* #define MEM_NONE 1 to compile out mem, i.e. have it all drop
* directly to calls to malloc, free, etc.
*
* #define MEM_NOMEMCOUNT 1 to remove checks on the number of free's
* matching the number of alloc's.
*
* Features always enabled:
*
* o mem_init() is called at startup, and mem_term() at
* close, which checks to see that the number of alloc's is
* the same as the number of free's.
* o Behavior on out-of-memory conditions can be controlled
* via mem_setexception().
*
* Extended debugging features:
*
* o Enabled by #define MEM_DEBUG 1 when compiling.
* o Check values are inserted before and after the alloc'ed data
* to detect pointer underruns and overruns.
* o Free'd pointers are checked against alloc'ed pointers.
* o Free'd storage is cleared to smoke out references to free'd data.
* o Realloc'd pointers are always changed, and the previous storage
* is cleared, to detect erroneous dependencies on the previous
* pointer.
* o The routine mem_checkptr() is provided to check an alloc'ed
* pointer.
*/
/********************* GLOBAL VARIABLES *************************/
extern int mem_inited; /* != 0 if mem package is initialized. */
/* Test this if you have other packages */
/* that depend on mem being initialized */
/********************* PUBLIC FUNCTIONS *************************/
/***********************************
* Set behavior when mem runs out of memory.
* Input:
* flag = MEM_ABORTMSG: Abort the program with the message
* 'Fatal error: out of memory' sent
* to stdout. This is the default behavior.
* MEM_ABORT: Abort the program with no message.
* MEM_RETNULL: Return NULL back to caller.
* MEM_CALLFP: Call application-specified function.
* fp must be supplied.
* fp Optional function pointer. Supplied if
* (flag == MEM_CALLFP). This function returns
* MEM_XXXXX, indicating what mem should do next.
* The function could do things like swap
* data out to disk to free up more memory.
* fp could also return:
* MEM_RETRY: Try again to allocate the space. Be
* careful not to go into an infinite loop.
* The type of fp is:
* int (*handler)(void)
*/
#if !MEM_NONE
#if __SC__ || __DMC__ || __GNUC__
enum MEM_E { MEM_ABORTMSG, MEM_ABORT, MEM_RETNULL, MEM_CALLFP, MEM_RETRY };
void mem_setexception(enum MEM_E,...);
#else
#define MEM_ABORTMSG 0
#define MEM_ABORT 1
#define MEM_RETNULL 2
#define MEM_CALLFP 3
#define MEM_RETRY 4
void mem_setexception(int,...);
#endif
#endif
/****************************
* Allocate space for string, copy string into it, and
* return pointer to the new string.
* This routine doesn't really belong here, but it is used so often
* that I gave up and put it here.
* Use:
* char *mem_strdup(const char *s);
* Returns:
* pointer to copied string if succussful.
* else returns NULL (if MEM_RETNULL)
*/
char *mem_strdup(const char *);
/**************************
* Function so we can have a pointer to function mem_free().
* This is needed since mem_free is sometimes defined as a macro,
* and then the preprocessor screws up.
* The pointer to mem_free() is used frequently with the list package.
* Use:
* void mem_freefp(void *p);
*/
/***************************
* Check for errors. This routine does a consistency check on the
* storage allocator, looking for corrupted data. It should be called
* when the application has CPU cycles to burn.
* Use:
* void mem_check(void);
*/
void mem_check(void);
/***************************
* Check ptr to see if it is in the range of allocated data.
* Cause assertion failure if it isn't.
*/
void mem_checkptr(void *ptr);
/***************************
* Allocate and return a pointer to numbytes of storage.
* Use:
* void *mem_malloc(unsigned numbytes);
* void *mem_calloc(unsigned numbytes); allocated memory is cleared
* Input:
* numbytes Number of bytes to allocate
* Returns:
* if (numbytes > 0)
* pointer to allocated data, NULL if out of memory
* else
* return NULL
*/
void *mem_malloc(unsigned);
void *mem_calloc(unsigned);
/*****************************
* Reallocate memory.
* Use:
* void *mem_realloc(void *ptr,unsigned numbytes);
*/
void *mem_realloc(void *,unsigned);
/*****************************
* Free memory allocated by mem_malloc(), mem_calloc() or mem_realloc().
* Use:
* void mem_free(void *ptr);
*/
void mem_free(void *);
/***************************
* Initialize memory handler.
* Use:
* void mem_init(void);
* Output:
* mem_inited = 1
*/
void mem_init(void);
/***************************
* Terminate memory handler. Useful for checking for errors.
* Use:
* void mem_term(void);
* Output:
* mem_inited = 0
*/
void mem_term(void);
/*******************************
* The mem_fxxx() functions are for allocating memory that will persist
* until program termination. The trick is that if the memory is never
* free'd, we can do a very fast allocation. If MEM_DEBUG is on, they
* act just like the regular mem functions, so it can be debugged.
*/
#if MEM_NONE
#define mem_fmalloc(u) malloc(u)
#define mem_fcalloc(u) calloc((u),1)
#define mem_ffree(p) ((void)0)
#define mem_fstrdup(p) strdup(p)
#else
#if MEM_DEBUG
#define mem_fmalloc mem_malloc
#define mem_fcalloc mem_calloc
#define mem_ffree mem_free
#define mem_fstrdup mem_strdup
#else
void *mem_fmalloc(unsigned);
void *mem_fcalloc(unsigned);
#define mem_ffree(p) ((void)0)
char *mem_fstrdup(const char *);
#endif
#endif
/***********************************
* C++ stuff.
*/
#if !MEM_NONE && MEM_DEBUG
#define mem_new !(__mem_line=__LINE__,__mem_file=__FILE__)? 0 : new
#define mem_delete (__mem_line=__LINE__,__mem_file=__FILE__), delete
extern int __mem_line;
extern char *__mem_file;
#endif
/* The following stuff forms the implementation rather than the
* definition, so ignore it.
*/
#if MEM_NONE
#define mem_inited 1
#define mem_strdup(p) strdup(p)
#define mem_malloc(u) malloc(u)
#define mem_calloc(u) calloc((u),1)
#define mem_realloc(p,u) realloc((p),(u))
#define mem_free(p) free(p)
#define mem_freefp free
#define mem_check() ((void)0)
#define mem_checkptr(p) ((void)(p))
#define mem_init() ((void)0)
#define mem_term() ((void)0)
#include <stdlib.h>
#else
#if MEM_DEBUG /* if creating debug version */
#define mem_strdup(p) mem_strdup_debug((p),__FILE__,__LINE__)
#define mem_malloc(u) mem_malloc_debug((u),__FILE__,__LINE__)
#define mem_calloc(u) mem_calloc_debug((u),__FILE__,__LINE__)
#define mem_realloc(p,u) mem_realloc_debug((p),(u),__FILE__,__LINE__)
#define mem_free(p) mem_free_debug((p),__FILE__,__LINE__)
char *mem_strdup_debug (const char *,const char *,int);
void *mem_calloc_debug (unsigned,const char *,int);
void *mem_malloc_debug (unsigned,const char *,int);
void *mem_realloc_debug (void *,unsigned,const char *,int);
void mem_free_debug (void *,const char *,int);
void mem_freefp (void *);
void mem_setnewfileline (void *,const char *,int);
#else
#define mem_freefp mem_free
#define mem_check()
#define mem_checkptr(p)
#endif /* MEM_DEBUG */
#endif /* MEM_NONE */
#endif /* MEM_H */