X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fxalloc.h;h=6881ea678d2cb833dc0a5f4a845423ab66346a68;hb=d5f7e64df8267621f5e17b2def101343f767b86e;hp=8668e198b7222b773a7e48573cccd05ed88e2bd2;hpb=89f2b4892655a929a506eff123c9126a88e2c8eb;p=gnulib.git diff --git a/lib/xalloc.h b/lib/xalloc.h index 8668e198b..6881ea678 100644 --- a/lib/xalloc.h +++ b/lib/xalloc.h @@ -1,5 +1,7 @@ /* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990-1998, 1999 Free Software Foundation, Inc. + + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2003, 2004 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,19 +15,19 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef XALLOC_H_ # define XALLOC_H_ -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif +# include + + +# ifdef __cplusplus +extern "C" { # endif + # ifndef __attribute__ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ # define __attribute__(x) @@ -36,52 +38,130 @@ # define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) # endif -/* Exit value when the requested amount of memory is not available. - It is initialized to EXIT_FAILURE, but the caller may set it to - some other value. */ -extern int xalloc_exit_failure; - -/* If this pointer is non-zero, run the specified function upon each - allocation failure. It is initialized to zero. */ -extern void (*xalloc_fail_func) PARAMS ((void)); - -/* If XALLOC_FAIL_FUNC is undefined or a function that returns, this - message must be non-NULL. It is translated via gettext. - The default value is "Memory exhausted". */ -extern char *const xalloc_msg_memory_exhausted; - -/* This function is always triggered when memory is exhausted. It is - in charge of honoring the three previous items. This is the +/* This function is always triggered when memory is exhausted. + It must be defined by the application, either explicitly + or by using gnulib's xalloc-die module. This is the function to call when one wants the program to die because of a memory allocation failure. */ -extern void xalloc_die PARAMS ((void)) ATTRIBUTE_NORETURN; - -void *xmalloc PARAMS ((size_t n)); -void *xcalloc PARAMS ((size_t n, size_t s)); -void *xrealloc PARAMS ((void *p, size_t n)); -char *xstrdup PARAMS ((const char *str)); - -# define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items))) -# define XCALLOC(Type, N_items) ((Type *) xcalloc (sizeof (Type), (N_items))) -# define XREALLOC(Ptr, Type, N_items) \ - ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items))) - -/* Declare and alloc memory for VAR of type TYPE. */ -# define NEW(Type, Var) Type *(Var) = XMALLOC (Type, 1) - -/* Free VAR only if non NULL. */ -# define XFREE(Var) \ - do { \ - if (Var) \ - free (Var); \ - } while (0) - -/* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */ -# define CCLONE(Src, Num) \ - (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num))) - -/* Return a malloc'ed copy of SRC. */ -# define CLONE(Src) CCLONE (Src, 1) +extern void xalloc_die (void) ATTRIBUTE_NORETURN; + +void *xmalloc (size_t s); +void *xnmalloc (size_t n, size_t s); +void *xzalloc (size_t s); +void *xcalloc (size_t n, size_t s); +void *xrealloc (void *p, size_t s); +void *xnrealloc (void *p, size_t n, size_t s); +void *x2realloc (void *p, size_t *pn); +void *x2nrealloc (void *p, size_t *pn, size_t s); +void *xmemdup (void const *p, size_t s); +char *xstrdup (char const *str); + +/* Return 1 if an array of N objects, each of size S, cannot exist due + to size arithmetic overflow. S must be positive and N must be + nonnegative. This is a macro, not an inline function, so that it + works correctly even when SIZE_MAX < N. + + By gnulib convention, SIZE_MAX represents overflow in size + calculations, so the conservative dividend to use here is + SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value. + However, malloc (SIZE_MAX) fails on all known hosts where + sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for + exactly-SIZE_MAX allocations on such hosts; this avoids a test and + branch when S is known to be 1. */ +# define xalloc_oversized(n, s) \ + ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) + +/* In the following macros, T must be an elementary or structure/union or + typedef'ed type, or a pointer to such a type. To apply one of the + following macros to a function pointer or array type, you need to typedef + it first and use the typedef name. */ + +/* Allocate an object of type T dynamically, with error checking. */ +/* extern T *XMALLOC (typename T); */ +#define XMALLOC(T) \ + ((T *) xmalloc (sizeof (T))) + +/* Allocate memory for NMEMB elements of type T, with error checking. */ +/* extern T *XNMALLOC (size_t nmemb, typename T); */ +#if HAVE_INLINE +/* xnmalloc performs a division and multiplication by sizeof (T). Arrange to + perform the division at compile-time and the multiplication with a factor + known at compile-time. */ +# define XNMALLOC(N,T) \ + ((T *) (sizeof (T) == 1 \ + ? xmalloc (N) \ + : xnboundedmalloc(N, (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / sizeof (T), sizeof (T)))) +static inline void * +xnboundedmalloc (size_t n, size_t bound, size_t s) +{ + if (n > bound) + xalloc_die (); + return xmalloc (n * s); +} +#else +# define XNMALLOC(N,T) \ + ((T *) (sizeof (T) == 1 ? xmalloc (N) : xnmalloc (N, sizeof (T)))) +#endif + +/* Allocate an object of type T dynamically, with error checking, + and zero it. */ +/* extern T *XZALLOC (typename T); */ +#define XZALLOC(T) \ + ((T *) xzalloc (sizeof (T))) + +/* Allocate memory for NMEMB elements of type T, with error checking, + and zero it. */ +/* extern T *XCALLOC (size_t nmemb, typename T); */ +#define XCALLOC(N,T) \ + ((T *) xcalloc (N, sizeof (T))) + +/* Return a pointer to a new buffer of N bytes. This is like xmalloc, + except it returns char *. + xcharalloc (N) is equivalent to XNMALLOC (N, char). */ +static inline char * +xcharalloc (size_t n) +{ + return (char *) xmalloc (n); +} + +# ifdef __cplusplus +} + +/* C++ does not allow conversions from void * to other pointer types + without a cast. Use templates to work around the problem when + possible. */ + +template inline T * +xrealloc (T *p, size_t s) +{ + return (T *) xrealloc ((void *) p, s); +} + +template inline T * +xnrealloc (T *p, size_t n, size_t s) +{ + return (T *) xnrealloc ((void *) p, n, s); +} + +template inline T * +x2realloc (T *p, size_t *pn) +{ + return (T *) x2realloc ((void *) p, pn); +} + +template inline T * +x2nrealloc (T *p, size_t *pn, size_t s) +{ + return (T *) x2nrealloc ((void *) p, pn, s); +} + +template inline T * +xmemdup (T const *p, size_t s) +{ + return (T *) xmemdup ((void const *) p, s); +} + +# endif #endif /* !XALLOC_H_ */