source: trunk/essentials/sys-apps/findutils/lib/extendbuf.c

Last change on this file was 3170, checked in by bird, 18 years ago

findutils 4.3.2

File size: 2.3 KB
Line 
1/* extendbuf.c -- manage a dynamically-allocated buffer
2
3 Copyright 2004 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 2, or (at your option)
8 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, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19/* Written by James Yougnman <jay@gnu.org>. */
20
21#if HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include <stddef.h>
26#include <stdlib.h>
27#include <assert.h>
28#include <errno.h>
29
30#include "xalloc.h"
31#include "extendbuf.h"
32
33
34/* We initially use a small default size to ensure that this code
35 * gets exercised.
36 */
37#ifndef SIZE_DEFAULT
38# define SIZE_DEFAULT 16
39#endif
40
41static size_t
42decide_size(size_t current, size_t wanted)
43{
44 size_t newsize;
45
46 if (0 == current)
47 newsize = SIZE_DEFAULT;
48 else
49 newsize = current;
50
51 while (newsize < wanted)
52 {
53 if (2 * newsize < newsize)
54 xalloc_die ();
55 newsize *= 2;
56 }
57 return newsize;
58}
59
60
61void *
62extendbuf(void* existing, size_t wanted, size_t *allocated)
63{
64 int saved_errno;
65 size_t newsize;
66 void *result; /* leave uninitialised to allow static code checkers to identify bugs */
67
68 saved_errno = errno;
69
70 assert(wanted > 0u);
71 newsize = decide_size(*allocated, wanted);
72
73 if ( (*allocated) == 0 )
74 {
75 /* Sanity check: If there is no existing allocation size, there
76 * must be no existing allocated buffer.
77 */
78 assert(NULL == existing);
79
80 (*allocated) = newsize;
81 result = xmalloc(newsize);
82 }
83 else
84 {
85 if (newsize != (*allocated) )
86 {
87 (*allocated) = newsize;
88 result = xrealloc (existing, newsize);
89
90 }
91 else
92 {
93 result = existing;
94 }
95 }
96
97 if (result)
98 {
99 /* xmalloc() or xrealloc() may have changed errno, but in the
100 success case we want to preserve the previous value.
101 */
102 errno = saved_errno;
103 }
104 return result;
105}
Note: See TracBrowser for help on using the repository browser.