OpenCoverage

obstack.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/lib/obstack.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* obstack.c - subroutines used implicitly by object stack macros-
2 Copyright (C) 1988-2018 Free Software Foundation, Inc.-
3 This file is part of the GNU C Library.-
4-
5 The GNU C Library is free software; you can redistribute it and/or-
6 modify it under the terms of the GNU General Public-
7 License as published by the Free Software Foundation; either-
8 version 3 of the License, or (at your option) any later version.-
9-
10 The GNU C Library 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 GNU-
13 General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public-
16 License along with the GNU C Library; if not, see-
17 <https://www.gnu.org/licenses/>. */-
18-
19-
20#ifdef _LIBC-
21# include <obstack.h>-
22#else-
23# include <config.h>-
24# include "obstack.h"-
25#endif-
26-
27/* NOTE BEFORE MODIFYING THIS FILE: _OBSTACK_INTERFACE_VERSION in-
28 obstack.h must be incremented whenever callers compiled using an old-
29 obstack.h can no longer properly call the functions in this file. */-
30-
31/* Comment out all this code if we are using the GNU C Library, and are not-
32 actually compiling the library itself, and the installed library-
33 supports the same library interface we do. This code is part of the GNU-
34 C Library, but also included in many other GNU distributions. Compiling-
35 and linking in this code is a waste when using the GNU C library-
36 (especially if it is a shared library). Rather than having every GNU-
37 program understand 'configure --with-gnu-libc' and omit the object-
38 files, it is simpler to just do this in the source for each such file. */-
39#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1-
40# include <gnu-versions.h>-
41# if (_GNU_OBSTACK_INTERFACE_VERSION == _OBSTACK_INTERFACE_VERSION \-
42 || (_GNU_OBSTACK_INTERFACE_VERSION == 1 \-
43 && _OBSTACK_INTERFACE_VERSION == 2 \-
44 && defined SIZEOF_INT && defined SIZEOF_SIZE_T \-
45 && SIZEOF_INT == SIZEOF_SIZE_T))-
46# define _OBSTACK_ELIDE_CODE-
47# endif-
48#endif-
49-
50#ifndef _OBSTACK_ELIDE_CODE-
51/* If GCC, or if an oddball (testing?) host that #defines __alignof__,-
52 use the already-supplied __alignof__. Otherwise, this must be Gnulib-
53 (as glibc assumes GCC); defer to Gnulib's alignof_type. */-
54# if !defined __GNUC__ && !defined __alignof__-
55# include <alignof.h>-
56# define __alignof__(type) alignof_type (type)-
57# endif-
58# include <stdlib.h>-
59# include <stdint.h>-
60-
61# ifndef MAX-
62# define MAX(a,b) ((a) > (b) ? (a) : (b))-
63# endif-
64-
65/* Determine default alignment. */-
66-
67/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.-
68 But in fact it might be less smart and round addresses to as much as-
69 DEFAULT_ROUNDING. So we prepare for it to do that.-
70-
71 DEFAULT_ALIGNMENT cannot be an enum constant; see gnulib's alignof.h. */-
72#define DEFAULT_ALIGNMENT MAX (__alignof__ (long double), \-
73 MAX (__alignof__ (uintmax_t), \-
74 __alignof__ (void *)))-
75#define DEFAULT_ROUNDING MAX (sizeof (long double), \-
76 MAX (sizeof (uintmax_t), \-
77 sizeof (void *)))-
78-
79/* Call functions with either the traditional malloc/free calling-
80 interface, or the mmalloc/mfree interface (that adds an extra first-
81 argument), based on the value of use_extra_arg. */-
82-
83static void *-
84call_chunkfun (struct obstack *h, size_t size)-
85{-
86 if (h->use_extra_arg)
h->use_extra_argDescription
TRUEnever evaluated
FALSEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
0-79
87 return h->chunkfun.extra (h->extra_arg, size);
never executed: return h->chunkfun.extra (h->extra_arg, size);
0
88 else-
89 return h->chunkfun.plain (size);
executed 79 times by 4 tests: return h->chunkfun.plain (size);
Executed by:
  • dircolors
  • ls
  • sort
  • wc
79
90}-
91-
92static void-
93call_freefun (struct obstack *h, void *old_chunk)-
94{-
95 if (h->use_extra_arg)
h->use_extra_argDescription
TRUEnever evaluated
FALSEevaluated 33 times by 1 test
Evaluated by:
  • wc
0-33
96 h->freefun.extra (h->extra_arg, old_chunk);
never executed: h->freefun.extra (h->extra_arg, old_chunk);
0
97 else-
98 h->freefun.plain (old_chunk);
executed 33 times by 1 test: h->freefun.plain (old_chunk);
Executed by:
  • wc
33
99}-
100-
101-
102/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).-
103 Objects start on multiples of ALIGNMENT (0 means use default).-
104-
105 Return nonzero if successful, calls obstack_alloc_failed_handler if-
106 allocation fails. */-
107-
108static int-
109_obstack_begin_worker (struct obstack *h,-
110 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment)-
111{-
112 struct _obstack_chunk *chunk; /* points to new chunk */-
113-
114 if (alignment == 0)
alignment == 0Description
TRUEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
FALSEnever evaluated
0-79
115 alignment = DEFAULT_ALIGNMENT;
executed 79 times by 4 tests: alignment = ((__alignof__ (long double)) > (((__alignof__ (uintmax_t)) > (__alignof__ (void *)) ? (__alignof__ (uintmax_t)) : (__alignof__ (void *)))) ? (__alignof__ (long double)) : (((__alignof__ (uintmax_t)) > (__alignof__ (void *)) ? (__alignof__ (uintmax_t)) : (__alignof__ (void *)))));
Executed by:
  • dircolors
  • ls
  • sort
  • wc
(__alignof__ (...__ (void *))))Description
TRUEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
FALSEnever evaluated
(__alignof__ (...of__ (void *))Description
TRUEnever evaluated
FALSEnever evaluated
0-79
116 if (size == 0)
size == 0Description
TRUEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
FALSEnever evaluated
0-79
117 /* Default size is what GNU malloc can fit in a 4096-byte block. */-
118 {-
119 /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.-
120 Use the values for range checking, because if range checking is off,-
121 the extra bytes won't be missed terribly, but if range checking is on-
122 and we used a larger request, a whole extra 4096 bytes would be-
123 allocated.-
124-
125 These number are irrelevant to the new GNU malloc. I suspect it is-
126 less sensitive to the size of the request. */-
127 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
(sizeof (long ...of (void *))))Description
TRUEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
FALSEnever evaluated
(sizeof (uintm...zeof (void *))Description
TRUEnever evaluated
FALSEnever evaluated
0-79
128 + 4 + DEFAULT_ROUNDING - 1)
(sizeof (long ...of (void *))))Description
TRUEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
FALSEnever evaluated
(sizeof (uintm...zeof (void *))Description
TRUEnever evaluated
FALSEnever evaluated
0-79
129 & ~(DEFAULT_ROUNDING - 1));-
130 size = 4096 - extra;-
131 }
executed 79 times by 4 tests: end of block
Executed by:
  • dircolors
  • ls
  • sort
  • wc
79
132-
133 h->chunk_size = size;-
134 h->alignment_mask = alignment - 1;-
135-
136 chunk = h->chunk = call_chunkfun (h, h->chunk_size);-
137 if (!chunk)
!chunkDescription
TRUEnever evaluated
FALSEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
0-79
138 (*obstack_alloc_failed_handler) ();
never executed: (*obstack_alloc_failed_handler) ();
0
139 h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEevaluated 79 times by 4 tests
Evaluated by:
  • dircolors
  • ls
  • sort
  • wc
0-79
140 alignment - 1);-
141 h->chunk_limit = chunk->limit = (char *) chunk + h->chunk_size;-
142 chunk->prev = 0;-
143 /* The initial chunk now contains no empty object. */-
144 h->maybe_empty_object = 0;-
145 h->alloc_failed = 0;-
146 return 1;
executed 79 times by 4 tests: return 1;
Executed by:
  • dircolors
  • ls
  • sort
  • wc
79
147}-
148-
149int-
150_obstack_begin (struct obstack *h,-
151 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,-
152 void *(*chunkfun) (size_t),-
153 void (*freefun) (void *))-
154{-
155 h->chunkfun.plain = chunkfun;-
156 h->freefun.plain = freefun;-
157 h->use_extra_arg = 0;-
158 return _obstack_begin_worker (h, size, alignment);
executed 79 times by 4 tests: return _obstack_begin_worker (h, size, alignment);
Executed by:
  • dircolors
  • ls
  • sort
  • wc
79
159}-
160-
161int-
162_obstack_begin_1 (struct obstack *h,-
163 _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment,-
164 void *(*chunkfun) (void *, size_t),-
165 void (*freefun) (void *, void *),-
166 void *arg)-
167{-
168 h->chunkfun.extra = chunkfun;-
169 h->freefun.extra = freefun;-
170 h->extra_arg = arg;-
171 h->use_extra_arg = 1;-
172 return _obstack_begin_worker (h, size, alignment);
never executed: return _obstack_begin_worker (h, size, alignment);
0
173}-
174-
175/* Allocate a new current chunk for the obstack *H-
176 on the assumption that LENGTH bytes need to be added-
177 to the current object, or a new object of length LENGTH allocated.-
178 Copies any partial object from the end of the old chunk-
179 to the beginning of the new one. */-
180-
181void-
182_obstack_newchunk (struct obstack *h, _OBSTACK_SIZE_T length)-
183{-
184 struct _obstack_chunk *old_chunk = h->chunk;-
185 struct _obstack_chunk *new_chunk = 0;-
186 size_t obj_size = h->next_free - h->object_base;-
187 char *object_base;-
188-
189 /* Compute size for new chunk. */-
190 size_t sum1 = obj_size + length;-
191 size_t sum2 = sum1 + h->alignment_mask;-
192 size_t new_size = sum2 + (obj_size >> 3) + 100;-
193 if (new_size < sum2)
new_size < sum2Description
TRUEnever evaluated
FALSEnever evaluated
0
194 new_size = sum2;
never executed: new_size = sum2;
0
195 if (new_size < h->chunk_size)
new_size < h->chunk_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
196 new_size = h->chunk_size;
never executed: new_size = h->chunk_size;
0
197-
198 /* Allocate and initialize the new chunk. */-
199 if (obj_size <= sum1 && sum1 <= sum2)
obj_size <= sum1Description
TRUEnever evaluated
FALSEnever evaluated
sum1 <= sum2Description
TRUEnever evaluated
FALSEnever evaluated
0
200 new_chunk = call_chunkfun (h, new_size);
never executed: new_chunk = call_chunkfun (h, new_size);
0
201 if (!new_chunk)
!new_chunkDescription
TRUEnever evaluated
FALSEnever evaluated
0
202 (*obstack_alloc_failed_handler)();
never executed: (*obstack_alloc_failed_handler)();
0
203 h->chunk = new_chunk;-
204 new_chunk->prev = old_chunk;-
205 new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;-
206-
207 /* Compute an aligned object_base in the new chunk */-
208 object_base =-
209 __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEnever evaluated
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEnever evaluated
0
210-
211 /* Move the existing object to the new chunk. */-
212 memcpy (object_base, h->object_base, obj_size);-
213-
214 /* If the object just copied was the only data in OLD_CHUNK,-
215 free that chunk and remove it from the chain.-
216 But not if that chunk might contain an empty object. */-
217 if (!h->maybe_empty_object
!h->maybe_empty_objectDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 && (h->object_base
(h->object_bas...ment_mask))) )Description
TRUEnever evaluated
FALSEnever evaluated
0
219 == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEnever evaluated
sizeof (ptrdif...izeof (void *)Description
TRUEnever evaluated
FALSEnever evaluated
(h->object_bas...ment_mask))) )Description
TRUEnever evaluated
FALSEnever evaluated
0
220 h->alignment_mask)))
(h->object_bas...ment_mask))) )Description
TRUEnever evaluated
FALSEnever evaluated
0
221 {-
222 new_chunk->prev = old_chunk->prev;-
223 call_freefun (h, old_chunk);-
224 }
never executed: end of block
0
225-
226 h->object_base = object_base;-
227 h->next_free = h->object_base + obj_size;-
228 /* The new chunk certainly contains no empty object yet. */-
229 h->maybe_empty_object = 0;-
230}
never executed: end of block
0
231-
232/* Return nonzero if object OBJ has been allocated from obstack H.-
233 This is here for debugging.-
234 If you use it in a program, you are probably losing. */-
235-
236/* Suppress -Wmissing-prototypes warning. We don't want to declare this in-
237 obstack.h because it is just for debugging. */-
238int _obstack_allocated_p (struct obstack *h, void *obj) __attribute_pure__;-
239-
240int-
241_obstack_allocated_p (struct obstack *h, void *obj)-
242{-
243 struct _obstack_chunk *lp; /* below addr of any objects in this chunk */-
244 struct _obstack_chunk *plp; /* point to previous chunk if any */-
245-
246 lp = (h)->chunk;-
247 /* We use >= rather than > since the object cannot be exactly at-
248 the beginning of the chunk but might be an empty object exactly-
249 at the end of an adjacent chunk. */-
250 while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
lp != 0Description
TRUEnever evaluated
FALSEnever evaluated
(void *) lp >= objDescription
TRUEnever evaluated
FALSEnever evaluated
(void *) (lp)->limit < objDescription
TRUEnever evaluated
FALSEnever evaluated
0
251 {-
252 plp = lp->prev;-
253 lp = plp;-
254 }
never executed: end of block
0
255 return lp != 0;
never executed: return lp != 0;
0
256}-
257-
258/* Free objects in obstack H, including OBJ and everything allocate-
259 more recently than OBJ. If OBJ is zero, free everything in H. */-
260-
261void-
262_obstack_free (struct obstack *h, void *obj)-
263{-
264 struct _obstack_chunk *lp; /* below addr of any objects in this chunk */-
265 struct _obstack_chunk *plp; /* point to previous chunk if any */-
266-
267 lp = h->chunk;-
268 /* We use >= because there cannot be an object at the beginning of a chunk.-
269 But there can be an empty object at that address-
270 at the end of another chunk. */-
271 while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
lp != 0Description
TRUEevaluated 33 times by 1 test
Evaluated by:
  • wc
FALSEevaluated 33 times by 1 test
Evaluated by:
  • wc
(void *) lp >= objDescription
TRUEevaluated 33 times by 1 test
Evaluated by:
  • wc
FALSEnever evaluated
(void *) (lp)->limit < objDescription
TRUEnever evaluated
FALSEnever evaluated
0-33
272 {-
273 plp = lp->prev;-
274 call_freefun (h, lp);-
275 lp = plp;-
276 /* If we switch chunks, we can't tell whether the new current-
277 chunk contains an empty object, so assume that it may. */-
278 h->maybe_empty_object = 1;-
279 }
executed 33 times by 1 test: end of block
Executed by:
  • wc
33
280 if (lp)
lpDescription
TRUEnever evaluated
FALSEevaluated 33 times by 1 test
Evaluated by:
  • wc
0-33
281 {-
282 h->object_base = h->next_free = (char *) (obj);-
283 h->chunk_limit = lp->limit;-
284 h->chunk = lp;-
285 }
never executed: end of block
0
286 else if (obj != 0)
obj != 0Description
TRUEnever evaluated
FALSEevaluated 33 times by 1 test
Evaluated by:
  • wc
0-33
287 /* obj is not in any of the chunks! */-
288 abort ();
never executed: abort ();
0
289}
executed 33 times by 1 test: end of block
Executed by:
  • wc
33
290-
291_OBSTACK_SIZE_T-
292_obstack_memory_used (struct obstack *h)-
293{-
294 struct _obstack_chunk *lp;-
295 _OBSTACK_SIZE_T nbytes = 0;-
296-
297 for (lp = h->chunk; lp != 0; lp = lp->prev)
lp != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
298 {-
299 nbytes += lp->limit - (char *) lp;-
300 }
never executed: end of block
0
301 return nbytes;
never executed: return nbytes;
0
302}-
303-
304# ifndef _OBSTACK_NO_ERROR_HANDLER-
305/* Define the error handler. */-
306# include <stdio.h>-
307-
308/* Exit value used when 'print_and_abort' is used. */-
309# ifdef _LIBC-
310int obstack_exit_failure = EXIT_FAILURE;-
311# else-
312# include "exitfail.h"-
313# define obstack_exit_failure exit_failure-
314# endif-
315-
316# ifdef _LIBC-
317# include <libintl.h>-
318# else-
319# include "gettext.h"-
320# endif-
321# ifndef _-
322# define _(msgid) gettext (msgid)-
323# endif-
324-
325# ifdef _LIBC-
326# include <libio/iolibio.h>-
327# endif-
328-
329static _Noreturn void-
330print_and_abort (void)-
331{-
332 /* Don't change any of these strings. Yes, it would be possible to add-
333 the newline to the string and use fputs or so. But this must not-
334 happen because the "memory exhausted" message appears in other places-
335 like this and the translation should be reused instead of creating-
336 a very similar string which requires a separate translation. */-
337# ifdef _LIBC-
338 (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));-
339# else-
340 fprintf (stderr, "%s\n", _("memory exhausted"));-
341# endif-
342 exit (obstack_exit_failure);
never executed: exit (exit_failure);
0
343}-
344-
345/* The functions allocating more room by calling 'obstack_chunk_alloc'-
346 jump to the handler pointed to by 'obstack_alloc_failed_handler'.-
347 This can be set to a user defined function which should either-
348 abort gracefully or use longjump - but shouldn't return. This-
349 variable by default points to the internal function-
350 'print_and_abort'. */-
351__attribute_noreturn__ void (*obstack_alloc_failed_handler) (void)-
352 = print_and_abort;-
353# endif /* !_OBSTACK_NO_ERROR_HANDLER */-
354#endif /* !_OBSTACK_ELIDE_CODE */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2