LCOV - code coverage report
Current view: top level - lib - xalloc.h (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 21 0.0 %
Date: 2017-08-04 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* xalloc.h -- malloc with out-of-memory checking
       2             : 
       3             :    Copyright (C) 1990-2000, 2003-2004, 2006-2016 Free Software Foundation, Inc.
       4             : 
       5             :    This program is free software: you can redistribute it and/or modify
       6             :    it under the terms of the GNU General Public License as published by
       7             :    the Free Software Foundation; either version 3 of the License, or
       8             :    (at your option) any later version.
       9             : 
      10             :    This program is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :    GNU General Public License for more details.
      14             : 
      15             :    You should have received a copy of the GNU General Public License
      16             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      17             : 
      18             : #ifndef XALLOC_H_
      19             : #define XALLOC_H_
      20             : 
      21             : #include <stddef.h>
      22             : 
      23             : #include "xalloc-oversized.h"
      24             : 
      25             : #ifndef _GL_INLINE_HEADER_BEGIN
      26             :  #error "Please include config.h first."
      27             : #endif
      28             : _GL_INLINE_HEADER_BEGIN
      29             : #ifndef XALLOC_INLINE
      30             : # define XALLOC_INLINE _GL_INLINE
      31             : #endif
      32             : 
      33             : #ifdef __cplusplus
      34             : extern "C" {
      35             : #endif
      36             : 
      37             : 
      38             : #if __GNUC__ >= 3
      39             : # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
      40             : #else
      41             : # define _GL_ATTRIBUTE_MALLOC
      42             : #endif
      43             : 
      44             : #if ! defined __clang__ && \
      45             :     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
      46             : # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
      47             : #else
      48             : # define _GL_ATTRIBUTE_ALLOC_SIZE(args)
      49             : #endif
      50             : 
      51             : /* This function is always triggered when memory is exhausted.
      52             :    It must be defined by the application, either explicitly
      53             :    or by using gnulib's xalloc-die module.  This is the
      54             :    function to call when one wants the program to die because of a
      55             :    memory allocation failure.  */
      56             : extern _Noreturn void xalloc_die (void);
      57             : 
      58             : void *xmalloc (size_t s)
      59             :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
      60             : void *xzalloc (size_t s)
      61             :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
      62             : void *xcalloc (size_t n, size_t s)
      63             :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
      64             : void *xrealloc (void *p, size_t s)
      65             :       _GL_ATTRIBUTE_ALLOC_SIZE ((2));
      66             : void *x2realloc (void *p, size_t *pn);
      67             : void *xmemdup (void const *p, size_t s)
      68             :       _GL_ATTRIBUTE_ALLOC_SIZE ((2));
      69             : char *xstrdup (char const *str)
      70             :       _GL_ATTRIBUTE_MALLOC;
      71             : 
      72             : /* In the following macros, T must be an elementary or structure/union or
      73             :    typedef'ed type, or a pointer to such a type.  To apply one of the
      74             :    following macros to a function pointer or array type, you need to typedef
      75             :    it first and use the typedef name.  */
      76             : 
      77             : /* Allocate an object of type T dynamically, with error checking.  */
      78             : /* extern t *XMALLOC (typename t); */
      79             : #define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
      80             : 
      81             : /* Allocate memory for N elements of type T, with error checking.  */
      82             : /* extern t *XNMALLOC (size_t n, typename t); */
      83             : #define XNMALLOC(n, t) \
      84             :    ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
      85             : 
      86             : /* Allocate an object of type T dynamically, with error checking,
      87             :    and zero it.  */
      88             : /* extern t *XZALLOC (typename t); */
      89             : #define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
      90             : 
      91             : /* Allocate memory for N elements of type T, with error checking,
      92             :    and zero it.  */
      93             : /* extern t *XCALLOC (size_t n, typename t); */
      94             : #define XCALLOC(n, t) \
      95             :    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
      96             : 
      97             : 
      98             : /* Allocate an array of N objects, each with S bytes of memory,
      99             :    dynamically, with error checking.  S must be nonzero.  */
     100             : 
     101             : XALLOC_INLINE void *xnmalloc (size_t n, size_t s)
     102             :                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
     103             : XALLOC_INLINE void *
     104           0 : xnmalloc (size_t n, size_t s)
     105             : {
     106           0 :   if (xalloc_oversized (n, s))
     107           0 :     xalloc_die ();
     108           0 :   return xmalloc (n * s);
     109             : }
     110             : 
     111             : /* Change the size of an allocated block of memory P to an array of N
     112             :    objects each of S bytes, with error checking.  S must be nonzero.  */
     113             : 
     114             : XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s)
     115             :                     _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
     116             : XALLOC_INLINE void *
     117           0 : xnrealloc (void *p, size_t n, size_t s)
     118             : {
     119           0 :   if (xalloc_oversized (n, s))
     120           0 :     xalloc_die ();
     121           0 :   return xrealloc (p, n * s);
     122             : }
     123             : 
     124             : /* If P is null, allocate a block of at least *PN such objects;
     125             :    otherwise, reallocate P so that it contains more than *PN objects
     126             :    each of S bytes.  S must be nonzero.  Set *PN to the new number of
     127             :    objects, and return the pointer to the new block.  *PN is never set
     128             :    to zero, and the returned pointer is never null.
     129             : 
     130             :    Repeated reallocations are guaranteed to make progress, either by
     131             :    allocating an initial block with a nonzero size, or by allocating a
     132             :    larger block.
     133             : 
     134             :    In the following implementation, nonzero sizes are increased by a
     135             :    factor of approximately 1.5 so that repeated reallocations have
     136             :    O(N) overall cost rather than O(N**2) cost, but the
     137             :    specification for this function does not guarantee that rate.
     138             : 
     139             :    Here is an example of use:
     140             : 
     141             :      int *p = NULL;
     142             :      size_t used = 0;
     143             :      size_t allocated = 0;
     144             : 
     145             :      void
     146             :      append_int (int value)
     147             :        {
     148             :          if (used == allocated)
     149             :            p = x2nrealloc (p, &allocated, sizeof *p);
     150             :          p[used++] = value;
     151             :        }
     152             : 
     153             :    This causes x2nrealloc to allocate a block of some nonzero size the
     154             :    first time it is called.
     155             : 
     156             :    To have finer-grained control over the initial size, set *PN to a
     157             :    nonzero value before calling this function with P == NULL.  For
     158             :    example:
     159             : 
     160             :      int *p = NULL;
     161             :      size_t used = 0;
     162             :      size_t allocated = 0;
     163             :      size_t allocated1 = 1000;
     164             : 
     165             :      void
     166             :      append_int (int value)
     167             :        {
     168             :          if (used == allocated)
     169             :            {
     170             :              p = x2nrealloc (p, &allocated1, sizeof *p);
     171             :              allocated = allocated1;
     172             :            }
     173             :          p[used++] = value;
     174             :        }
     175             : 
     176             :    */
     177             : 
     178             : XALLOC_INLINE void *
     179           0 : x2nrealloc (void *p, size_t *pn, size_t s)
     180             : {
     181           0 :   size_t n = *pn;
     182             : 
     183           0 :   if (! p)
     184             :     {
     185           0 :       if (! n)
     186             :         {
     187             :           /* The approximate size to use for initial small allocation
     188             :              requests, when the invoking code specifies an old size of
     189             :              zero.  This is the largest "small" request for the GNU C
     190             :              library malloc.  */
     191             :           enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
     192             : 
     193           0 :           n = DEFAULT_MXFAST / s;
     194           0 :           n += !n;
     195             :         }
     196             :     }
     197             :   else
     198             :     {
     199             :       /* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0.
     200             :          Check for overflow, so that N * S stays in size_t range.
     201             :          The check may be slightly conservative, but an exact check isn't
     202             :          worth the trouble.  */
     203           0 :       if ((size_t) -1 / 3 * 2 / s <= n)
     204           0 :         xalloc_die ();
     205           0 :       n += n / 2 + 1;
     206             :     }
     207             : 
     208           0 :   *pn = n;
     209           0 :   return xrealloc (p, n * s);
     210             : }
     211             : 
     212             : /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
     213             :    except it returns char *.  */
     214             : 
     215             : XALLOC_INLINE char *xcharalloc (size_t n)
     216             :                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
     217             : XALLOC_INLINE char *
     218           0 : xcharalloc (size_t n)
     219             : {
     220           0 :   return XNMALLOC (n, char);
     221             : }
     222             : 
     223             : #ifdef __cplusplus
     224             : }
     225             : 
     226             : /* C++ does not allow conversions from void * to other pointer types
     227             :    without a cast.  Use templates to work around the problem when
     228             :    possible.  */
     229             : 
     230             : template <typename T> inline T *
     231             : xrealloc (T *p, size_t s)
     232             : {
     233             :   return (T *) xrealloc ((void *) p, s);
     234             : }
     235             : 
     236             : template <typename T> inline T *
     237             : xnrealloc (T *p, size_t n, size_t s)
     238             : {
     239             :   return (T *) xnrealloc ((void *) p, n, s);
     240             : }
     241             : 
     242             : template <typename T> inline T *
     243             : x2realloc (T *p, size_t *pn)
     244             : {
     245             :   return (T *) x2realloc ((void *) p, pn);
     246             : }
     247             : 
     248             : template <typename T> inline T *
     249             : x2nrealloc (T *p, size_t *pn, size_t s)
     250             : {
     251             :   return (T *) x2nrealloc ((void *) p, pn, s);
     252             : }
     253             : 
     254             : template <typename T> inline T *
     255             : xmemdup (T const *p, size_t s)
     256             : {
     257             :   return (T *) xmemdup ((void const *) p, s);
     258             : }
     259             : 
     260             : #endif
     261             : 
     262             : _GL_INLINE_HEADER_END
     263             : 
     264             : #endif /* !XALLOC_H_ */

Generated by: LCOV version 1.10