~ubuntu-branches/ubuntu/vivid/diffutils/vivid

« back to all changes in this revision

Viewing changes to lib/xalloc.h

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2010-02-13 11:49:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100213114900-09lz8jx6wct52qp8
Tags: 1:2.9-1
* New upstream release, now under GPL version 3 or later.
* There is now a --tab-size option. Closes: #82923.
* Manpage for cmp describes exit status. Closes: #200614.
* Manpage for diff describes exit status. Closes: #228441, #473233.
* The file de.po is now more recent. Closes: #313686.
* Fixed bad sdiff behaviour. Closes: #320222.
* Added wdiff to Suggests. Closes: #324627.
* Fixed cmp behaviour regarding stdout and stderr. Closes: #356083.
* The file ru.po is now more recent. Closes: #409274.
* The file es.po is now more recent. Closes: #418005, #481708.
* The file nl.po is now more recent. Closes: #427370.
* Modified watch file to use http instead of ftp.
* Removed .comment section from executables.
* Added Homepage field to control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* xalloc.h -- malloc with out-of-memory checking
2
 
   Copyright (C) 1990-1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3
 
 
4
 
   This program is free software; you can redistribute it and/or modify
 
2
 
 
3
   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 
4
   2000, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
 
5
   Inc.
 
6
 
 
7
   This program is free software: you can redistribute it and/or modify
5
8
   it under the terms of the GNU General Public License as published by
6
 
   the Free Software Foundation; either version 2, or (at your option)
7
 
   any later version.
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
8
11
 
9
12
   This program is distributed in the hope that it will be useful,
10
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
15
   GNU General Public License for more details.
13
16
 
14
17
   You should have received a copy of the GNU General Public License
15
 
   along with this program; if not, write to the Free Software Foundation,
16
 
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
19
 
18
20
#ifndef XALLOC_H_
19
21
# define XALLOC_H_
20
22
 
21
 
# ifndef PARAMS
22
 
#  if defined PROTOTYPES || (defined __STDC__ && __STDC__)
23
 
#   define PARAMS(Args) Args
24
 
#  else
25
 
#   define PARAMS(Args) ()
26
 
#  endif
 
23
# include <stddef.h>
 
24
 
 
25
 
 
26
# ifdef __cplusplus
 
27
extern "C" {
27
28
# endif
28
29
 
 
30
 
29
31
# ifndef __attribute__
30
 
#  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
 
32
#  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
31
33
#   define __attribute__(x)
32
34
#  endif
33
35
# endif
36
38
#  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
37
39
# endif
38
40
 
39
 
/* If this pointer is non-zero, run the specified function upon each
40
 
   allocation failure.  It is initialized to zero. */
41
 
extern void (*xalloc_fail_func) PARAMS ((void));
42
 
 
43
 
/* If XALLOC_FAIL_FUNC is undefined or a function that returns, this
44
 
   message is output.  It is translated via gettext.
45
 
   Its value is "memory exhausted".  */
46
 
extern char const xalloc_msg_memory_exhausted[];
47
 
 
48
 
/* This function is always triggered when memory is exhausted.  It is
49
 
   in charge of honoring the three previous items.  This is the
 
41
# ifndef ATTRIBUTE_MALLOC
 
42
#  if __GNUC__ >= 3
 
43
#   define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
 
44
#  else
 
45
#   define ATTRIBUTE_MALLOC
 
46
#  endif
 
47
# endif
 
48
 
 
49
/* This function is always triggered when memory is exhausted.
 
50
   It must be defined by the application, either explicitly
 
51
   or by using gnulib's xalloc-die module.  This is the
50
52
   function to call when one wants the program to die because of a
51
53
   memory allocation failure.  */
52
 
extern void xalloc_die PARAMS ((void)) ATTRIBUTE_NORETURN;
53
 
 
54
 
void *xmalloc PARAMS ((size_t n));
55
 
void *xcalloc PARAMS ((size_t n, size_t s));
56
 
void *xrealloc PARAMS ((void *p, size_t n));
57
 
char *xstrdup PARAMS ((const char *str));
58
 
 
59
 
# define XMALLOC(Type, N_items) ((Type *) xmalloc (sizeof (Type) * (N_items)))
60
 
# define XCALLOC(Type, N_items) ((Type *) xcalloc (sizeof (Type), (N_items)))
61
 
# define XREALLOC(Ptr, Type, N_items) \
62
 
  ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_items)))
63
 
 
64
 
/* Declare and alloc memory for VAR of type TYPE. */
65
 
# define NEW(Type, Var)  Type *(Var) = XMALLOC (Type, 1)
66
 
 
67
 
/* Free VAR only if non NULL. */
68
 
# define XFREE(Var)     \
69
 
   do {                 \
70
 
      if (Var)          \
71
 
        free (Var);     \
72
 
   } while (0)
73
 
 
74
 
/* Return a pointer to a malloc'ed copy of the array SRC of NUM elements. */
75
 
# define CCLONE(Src, Num) \
76
 
  (memcpy (xmalloc (sizeof (*Src) * (Num)), (Src), sizeof (*Src) * (Num)))
77
 
 
78
 
/* Return a malloc'ed copy of SRC. */
79
 
# define CLONE(Src) CCLONE (Src, 1)
 
54
extern void xalloc_die (void) ATTRIBUTE_NORETURN;
 
55
 
 
56
void *xmalloc (size_t s) ATTRIBUTE_MALLOC;
 
57
void *xzalloc (size_t s) ATTRIBUTE_MALLOC;
 
58
void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
 
59
void *xrealloc (void *p, size_t s);
 
60
void *x2realloc (void *p, size_t *pn);
 
61
void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC;
 
62
char *xstrdup (char const *str) ATTRIBUTE_MALLOC;
 
63
 
 
64
/* Return 1 if an array of N objects, each of size S, cannot exist due
 
65
   to size arithmetic overflow.  S must be positive and N must be
 
66
   nonnegative.  This is a macro, not an inline function, so that it
 
67
   works correctly even when SIZE_MAX < N.
 
68
 
 
69
   By gnulib convention, SIZE_MAX represents overflow in size
 
70
   calculations, so the conservative dividend to use here is
 
71
   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
 
72
   However, malloc (SIZE_MAX) fails on all known hosts where
 
73
   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
 
74
   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
 
75
   branch when S is known to be 1.  */
 
76
# define xalloc_oversized(n, s) \
 
77
    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
 
78
 
 
79
 
 
80
/* In the following macros, T must be an elementary or structure/union or
 
81
   typedef'ed type, or a pointer to such a type.  To apply one of the
 
82
   following macros to a function pointer or array type, you need to typedef
 
83
   it first and use the typedef name.  */
 
84
 
 
85
/* Allocate an object of type T dynamically, with error checking.  */
 
86
/* extern t *XMALLOC (typename t); */
 
87
# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
 
88
 
 
89
/* Allocate memory for N elements of type T, with error checking.  */
 
90
/* extern t *XNMALLOC (size_t n, typename t); */
 
91
# define XNMALLOC(n, t) \
 
92
    ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
 
93
 
 
94
/* Allocate an object of type T dynamically, with error checking,
 
95
   and zero it.  */
 
96
/* extern t *XZALLOC (typename t); */
 
97
# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
 
98
 
 
99
/* Allocate memory for N elements of type T, with error checking,
 
100
   and zero it.  */
 
101
/* extern t *XCALLOC (size_t n, typename t); */
 
102
# define XCALLOC(n, t) \
 
103
    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
 
104
 
 
105
 
 
106
# if HAVE_INLINE
 
107
#  define static_inline static inline
 
108
# else
 
109
void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
 
110
void *xnrealloc (void *p, size_t n, size_t s);
 
111
void *x2nrealloc (void *p, size_t *pn, size_t s);
 
112
char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
 
113
# endif
 
114
 
 
115
# ifdef static_inline
 
116
 
 
117
/* Allocate an array of N objects, each with S bytes of memory,
 
118
   dynamically, with error checking.  S must be nonzero.  */
 
119
 
 
120
static_inline void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
 
121
static_inline void *
 
122
xnmalloc (size_t n, size_t s)
 
123
{
 
124
  if (xalloc_oversized (n, s))
 
125
    xalloc_die ();
 
126
  return xmalloc (n * s);
 
127
}
 
128
 
 
129
/* Change the size of an allocated block of memory P to an array of N
 
130
   objects each of S bytes, with error checking.  S must be nonzero.  */
 
131
 
 
132
static_inline void *
 
133
xnrealloc (void *p, size_t n, size_t s)
 
134
{
 
135
  if (xalloc_oversized (n, s))
 
136
    xalloc_die ();
 
137
  return xrealloc (p, n * s);
 
138
}
 
139
 
 
140
/* If P is null, allocate a block of at least *PN such objects;
 
141
   otherwise, reallocate P so that it contains more than *PN objects
 
142
   each of S bytes.  *PN must be nonzero unless P is null, and S must
 
143
   be nonzero.  Set *PN to the new number of objects, and return the
 
144
   pointer to the new block.  *PN is never set to zero, and the
 
145
   returned pointer is never null.
 
146
 
 
147
   Repeated reallocations are guaranteed to make progress, either by
 
148
   allocating an initial block with a nonzero size, or by allocating a
 
149
   larger block.
 
150
 
 
151
   In the following implementation, nonzero sizes are increased by a
 
152
   factor of approximately 1.5 so that repeated reallocations have
 
153
   O(N) overall cost rather than O(N**2) cost, but the
 
154
   specification for this function does not guarantee that rate.
 
155
 
 
156
   Here is an example of use:
 
157
 
 
158
     int *p = NULL;
 
159
     size_t used = 0;
 
160
     size_t allocated = 0;
 
161
 
 
162
     void
 
163
     append_int (int value)
 
164
       {
 
165
         if (used == allocated)
 
166
           p = x2nrealloc (p, &allocated, sizeof *p);
 
167
         p[used++] = value;
 
168
       }
 
169
 
 
170
   This causes x2nrealloc to allocate a block of some nonzero size the
 
171
   first time it is called.
 
172
 
 
173
   To have finer-grained control over the initial size, set *PN to a
 
174
   nonzero value before calling this function with P == NULL.  For
 
175
   example:
 
176
 
 
177
     int *p = NULL;
 
178
     size_t used = 0;
 
179
     size_t allocated = 0;
 
180
     size_t allocated1 = 1000;
 
181
 
 
182
     void
 
183
     append_int (int value)
 
184
       {
 
185
         if (used == allocated)
 
186
           {
 
187
             p = x2nrealloc (p, &allocated1, sizeof *p);
 
188
             allocated = allocated1;
 
189
           }
 
190
         p[used++] = value;
 
191
       }
 
192
 
 
193
   */
 
194
 
 
195
static_inline void *
 
196
x2nrealloc (void *p, size_t *pn, size_t s)
 
197
{
 
198
  size_t n = *pn;
 
199
 
 
200
  if (! p)
 
201
    {
 
202
      if (! n)
 
203
        {
 
204
          /* The approximate size to use for initial small allocation
 
205
             requests, when the invoking code specifies an old size of
 
206
             zero.  64 bytes is the largest "small" request for the
 
207
             GNU C library malloc.  */
 
208
          enum { DEFAULT_MXFAST = 64 };
 
209
 
 
210
          n = DEFAULT_MXFAST / s;
 
211
          n += !n;
 
212
        }
 
213
    }
 
214
  else
 
215
    {
 
216
      /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
 
217
         Check for overflow, so that N * S stays in size_t range.
 
218
         The check is slightly conservative, but an exact check isn't
 
219
         worth the trouble.  */
 
220
      if ((size_t) -1 / 3 * 2 / s <= n)
 
221
        xalloc_die ();
 
222
      n += (n + 1) / 2;
 
223
    }
 
224
 
 
225
  *pn = n;
 
226
  return xrealloc (p, n * s);
 
227
}
 
228
 
 
229
/* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
 
230
   except it returns char *.  */
 
231
 
 
232
static_inline char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
 
233
static_inline char *
 
234
xcharalloc (size_t n)
 
235
{
 
236
  return XNMALLOC (n, char);
 
237
}
 
238
 
 
239
# endif
 
240
 
 
241
# ifdef __cplusplus
 
242
}
 
243
 
 
244
/* C++ does not allow conversions from void * to other pointer types
 
245
   without a cast.  Use templates to work around the problem when
 
246
   possible.  */
 
247
 
 
248
template <typename T> inline T *
 
249
xrealloc (T *p, size_t s)
 
250
{
 
251
  return (T *) xrealloc ((void *) p, s);
 
252
}
 
253
 
 
254
template <typename T> inline T *
 
255
xnrealloc (T *p, size_t n, size_t s)
 
256
{
 
257
  return (T *) xnrealloc ((void *) p, n, s);
 
258
}
 
259
 
 
260
template <typename T> inline T *
 
261
x2realloc (T *p, size_t *pn)
 
262
{
 
263
  return (T *) x2realloc ((void *) p, pn);
 
264
}
 
265
 
 
266
template <typename T> inline T *
 
267
x2nrealloc (T *p, size_t *pn, size_t s)
 
268
{
 
269
  return (T *) x2nrealloc ((void *) p, pn, s);
 
270
}
 
271
 
 
272
template <typename T> inline T *
 
273
xmemdup (T const *p, size_t s)
 
274
{
 
275
  return (T *) xmemdup ((void const *) p, s);
 
276
}
 
277
 
 
278
# endif
80
279
 
81
280
 
82
281
#endif /* !XALLOC_H_ */