1 /* obstack.c - subroutines used implicitly by object stack macros
2 Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
3
4
5 NOTE: This source is derived from an old version taken from the GNU C
6 Library (glibc).
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
21 USA. */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "obstack.h"
28
29 /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
30 incremented whenever callers compiled using an old obstack.h can no
31 longer properly call the functions in this obstack.c. */
32 #define OBSTACK_INTERFACE_VERSION 1
33
34 /* Comment out all this code if we are using the GNU C Library, and are not
35 actually compiling the library itself, and the installed library
36 supports the same library interface we do. This code is part of the GNU
37 C Library, but also included in many other GNU distributions. Compiling
38 and linking in this code is a waste when using the GNU C library
39 (especially if it is a shared library). Rather than having every GNU
40 program understand `configure --with-gnu-libc' and omit the object
41 files, it is simpler to just do this in the source for each such file. */
42
43 #include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
44 #include <stdlib.h>
45 #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
46 #include <gnu-versions.h>
47 #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
48 #define ELIDE_CODE
49 #endif
50 #endif
51
52
53 #ifndef ELIDE_CODE
54
55
56 #define POINTER void *
57
58 /* Determine default alignment. */
59 struct fooalign {char x; double d;};
60 #define DEFAULT_ALIGNMENT \
61 ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
62 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
63 But in fact it might be less smart and round addresses to as much as
64 DEFAULT_ROUNDING. So we prepare for it to do that. */
65 union fooround {long x; double d;};
66 #define DEFAULT_ROUNDING (sizeof (union fooround))
67
68 /* When we copy a long block of data, this is the unit to do it with.
69 On some machines, copying successive ints does not work;
70 in such a case, redefine COPYING_UNIT to `long' (if that works)
71 or `char' as a last resort. */
72 #ifndef COPYING_UNIT
73 #define COPYING_UNIT int
74 #endif
75
76
77 /* The functions allocating more room by calling `obstack_chunk_alloc'
78 jump to the handler pointed to by `obstack_alloc_failed_handler'.
79 This variable by default points to the internal function
80 `print_and_abort'. */
81 static void print_and_abort (void);
82 void (*obstack_alloc_failed_handler) (void) = print_and_abort;
83
84 /* Exit value used when `print_and_abort' is used. */
85 #if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
86 #include <stdlib.h>
87 #endif
88 #ifndef EXIT_FAILURE
89 #define EXIT_FAILURE 1
90 #endif
91 int obstack_exit_failure = EXIT_FAILURE;
92
93 /* The non-GNU-C macros copy the obstack into this global variable
94 to avoid multiple evaluation. */
95
96 struct obstack *_obstack;
97
98 /* Define a macro that either calls functions with the traditional malloc/free
99 calling interface, or calls functions with the mmalloc/mfree interface
100 (that adds an extra first argument), based on the state of use_extra_arg.
101 For free, do not use ?:, since some compilers, like the MIPS compilers,
102 do not allow (expr) ? void : void. */
103
104 #if defined (__STDC__) && __STDC__
105 #define CALL_CHUNKFUN(h, size) \
106 (((h) -> use_extra_arg) \
107 ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
108 : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
109
110 #define CALL_FREEFUN(h, old_chunk) \
111 do { \
112 if ((h) -> use_extra_arg) \
113 (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
114 else \
115 (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
116 } while (0)
117 #else
118 #define CALL_CHUNKFUN(h, size) \
119 (((h) -> use_extra_arg) \
120 ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
121 : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
122
123 #define CALL_FREEFUN(h, old_chunk) \
124 do { \
125 if ((h) -> use_extra_arg) \
126 (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
127 else \
128 (*(void (*) ()) (h)->freefun) ((old_chunk)); \
129 } while (0)
130 #endif
131
132
133 /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
134 Objects start on multiples of ALIGNMENT (0 means use default).
135 CHUNKFUN is the function to use to allocate chunks,
136 and FREEFUN the function to free them.
137
138 Return nonzero if successful, zero if out of memory.
139 To recover from an out of memory error,
140 free up some memory, then call this again. */
141
142 int
_obstack_begin(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(long),void (* freefun)(void *))143 _obstack_begin (struct obstack *h, int size, int alignment,
144 POINTER (*chunkfun) (long), void (*freefun) (void *))
145 {
146 register struct _obstack_chunk *chunk; /* points to new chunk */
147
148 if (alignment == 0)
149 alignment = (int) DEFAULT_ALIGNMENT;
150 if (size == 0)
151 /* Default size is what GNU malloc can fit in a 4096-byte block. */
152 {
153 /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
154 Use the values for range checking, because if range checking is off,
155 the extra bytes won't be missed terribly, but if range checking is on
156 and we used a larger request, a whole extra 4096 bytes would be
157 allocated.
158
159 These number are irrelevant to the new GNU malloc. I suspect it is
160 less sensitive to the size of the request. */
161 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
162 + 4 + DEFAULT_ROUNDING - 1)
163 & ~(DEFAULT_ROUNDING - 1));
164 size = 4096 - extra;
165 }
166
167 h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
168 h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
169 h->chunk_size = size;
170 h->alignment_mask = alignment - 1;
171 h->use_extra_arg = 0;
172
173 chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
174 if (!chunk)
175 (*obstack_alloc_failed_handler) ();
176 h->next_free = h->object_base = chunk->contents;
177 h->chunk_limit = chunk->limit
178 = (char *) chunk + h->chunk_size;
179 chunk->prev = 0;
180 /* The initial chunk now contains no empty object. */
181 h->maybe_empty_object = 0;
182 h->alloc_failed = 0;
183 return 1;
184 }
185
186 int
_obstack_begin_1(struct obstack * h,int size,int alignment,POINTER (* chunkfun)(POINTER,long),void (* freefun)(POINTER,POINTER),POINTER arg)187 _obstack_begin_1 (struct obstack *h, int size, int alignment,
188 POINTER (*chunkfun) (POINTER, long),
189 void (*freefun) (POINTER, POINTER), POINTER arg)
190 {
191 register struct _obstack_chunk *chunk; /* points to new chunk */
192
193 if (alignment == 0)
194 alignment = (int) DEFAULT_ALIGNMENT;
195 if (size == 0)
196 /* Default size is what GNU malloc can fit in a 4096-byte block. */
197 {
198 /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
199 Use the values for range checking, because if range checking is off,
200 the extra bytes won't be missed terribly, but if range checking is on
201 and we used a larger request, a whole extra 4096 bytes would be
202 allocated.
203
204 These number are irrelevant to the new GNU malloc. I suspect it is
205 less sensitive to the size of the request. */
206 int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
207 + 4 + DEFAULT_ROUNDING - 1)
208 & ~(DEFAULT_ROUNDING - 1));
209 size = 4096 - extra;
210 }
211
212 h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
213 h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
214 h->chunk_size = size;
215 h->alignment_mask = alignment - 1;
216 h->extra_arg = arg;
217 h->use_extra_arg = 1;
218
219 chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
220 if (!chunk)
221 (*obstack_alloc_failed_handler) ();
222 h->next_free = h->object_base = chunk->contents;
223 h->chunk_limit = chunk->limit
224 = (char *) chunk + h->chunk_size;
225 chunk->prev = 0;
226 /* The initial chunk now contains no empty object. */
227 h->maybe_empty_object = 0;
228 h->alloc_failed = 0;
229 return 1;
230 }
231
232 /* Allocate a new current chunk for the obstack *H
233 on the assumption that LENGTH bytes need to be added
234 to the current object, or a new object of length LENGTH allocated.
235 Copies any partial object from the end of the old chunk
236 to the beginning of the new one. */
237
238 void
_obstack_newchunk(struct obstack * h,int length)239 _obstack_newchunk (struct obstack *h, int length)
240 {
241 register struct _obstack_chunk *old_chunk = h->chunk;
242 register struct _obstack_chunk *new_chunk;
243 register long new_size;
244 register long obj_size = h->next_free - h->object_base;
245 register long i;
246 long already;
247
248 /* Compute size for new chunk. */
249 new_size = (obj_size + length) + (obj_size >> 3) + 100;
250 if (new_size < h->chunk_size)
251 new_size = h->chunk_size;
252
253 /* Allocate and initialize the new chunk. */
254 new_chunk = CALL_CHUNKFUN (h, new_size);
255 if (!new_chunk)
256 (*obstack_alloc_failed_handler) ();
257 h->chunk = new_chunk;
258 new_chunk->prev = old_chunk;
259 new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
260
261 /* Move the existing object to the new chunk.
262 Word at a time is fast and is safe if the object
263 is sufficiently aligned. */
264 if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
265 {
266 for (i = obj_size / sizeof (COPYING_UNIT) - 1;
267 i >= 0; i--)
268 ((COPYING_UNIT *)new_chunk->contents)[i]
269 = ((COPYING_UNIT *)h->object_base)[i];
270 /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
271 but that can cross a page boundary on a machine
272 which does not do strict alignment for COPYING_UNITS. */
273 already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
274 }
275 else
276 already = 0;
277 /* Copy remaining bytes one by one. */
278 for (i = already; i < obj_size; i++)
279 new_chunk->contents[i] = h->object_base[i];
280
281 /* If the object just copied was the only data in OLD_CHUNK,
282 free that chunk and remove it from the chain.
283 But not if that chunk might contain an empty object. */
284 if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
285 {
286 new_chunk->prev = old_chunk->prev;
287 CALL_FREEFUN (h, old_chunk);
288 }
289
290 h->object_base = new_chunk->contents;
291 h->next_free = h->object_base + obj_size;
292 /* The new chunk certainly contains no empty object yet. */
293 h->maybe_empty_object = 0;
294 }
295
296 /* Return nonzero if object OBJ has been allocated from obstack H.
297 This is here for debugging.
298 If you use it in a program, you are probably losing. */
299
300 /* Suppress -Wmissing-prototypes warning. We don't want to declare this in
301 obstack.h because it is just for debugging. */
302 int _obstack_allocated_p (struct obstack *h, POINTER obj);
303
304 int
_obstack_allocated_p(struct obstack * h,POINTER obj)305 _obstack_allocated_p (struct obstack *h, POINTER obj)
306 {
307 register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
308 register struct _obstack_chunk *plp; /* point to previous chunk if any */
309
310 lp = (h)->chunk;
311 /* We use >= rather than > since the object cannot be exactly at
312 the beginning of the chunk but might be an empty object exactly
313 at the end of an adjacent chunk. */
314 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
315 {
316 plp = lp->prev;
317 lp = plp;
318 }
319 return lp != 0;
320 }
321
322 /* Free objects in obstack H, including OBJ and everything allocate
323 more recently than OBJ. If OBJ is zero, free everything in H. */
324
325 #undef obstack_free
326
327 /* This function has two names with identical definitions.
328 This is the first one, called from non-ANSI code. */
329
330 void
_obstack_free(struct obstack * h,POINTER obj)331 _obstack_free (struct obstack *h, POINTER obj)
332 {
333 register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
334 register struct _obstack_chunk *plp; /* point to previous chunk if any */
335
336 lp = h->chunk;
337 /* We use >= because there cannot be an object at the beginning of a chunk.
338 But there can be an empty object at that address
339 at the end of another chunk. */
340 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
341 {
342 plp = lp->prev;
343 CALL_FREEFUN (h, lp);
344 lp = plp;
345 /* If we switch chunks, we can't tell whether the new current
346 chunk contains an empty object, so assume that it may. */
347 h->maybe_empty_object = 1;
348 }
349 if (lp)
350 {
351 h->object_base = h->next_free = (char *) (obj);
352 h->chunk_limit = lp->limit;
353 h->chunk = lp;
354 }
355 else if (obj != 0)
356 /* obj is not in any of the chunks! */
357 abort ();
358 }
359
360 /* This function is used from ANSI code. */
361
362 void
obstack_free(struct obstack * h,POINTER obj)363 obstack_free (struct obstack *h, POINTER obj)
364 {
365 register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
366 register struct _obstack_chunk *plp; /* point to previous chunk if any */
367
368 lp = h->chunk;
369 /* We use >= because there cannot be an object at the beginning of a chunk.
370 But there can be an empty object at that address
371 at the end of another chunk. */
372 while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
373 {
374 plp = lp->prev;
375 CALL_FREEFUN (h, lp);
376 lp = plp;
377 /* If we switch chunks, we can't tell whether the new current
378 chunk contains an empty object, so assume that it may. */
379 h->maybe_empty_object = 1;
380 }
381 if (lp)
382 {
383 h->object_base = h->next_free = (char *) (obj);
384 h->chunk_limit = lp->limit;
385 h->chunk = lp;
386 }
387 else if (obj != 0)
388 /* obj is not in any of the chunks! */
389 abort ();
390 }
391
392 int
_obstack_memory_used(struct obstack * h)393 _obstack_memory_used (struct obstack *h)
394 {
395 register struct _obstack_chunk* lp;
396 register int nbytes = 0;
397
398 for (lp = h->chunk; lp != 0; lp = lp->prev)
399 {
400 nbytes += lp->limit - (char *) lp;
401 }
402 return nbytes;
403 }
404
405 /* Define the error handler. */
406 #ifndef _
407 # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
408 # include <libintl.h>
409 # ifndef _
410 # define _(Str) gettext (Str)
411 # endif
412 # else
413 # define _(Str) (Str)
414 # endif
415 #endif
416
417 static void
print_and_abort(void)418 print_and_abort (void)
419 {
420 fputs (_("memory exhausted\n"), stderr);
421 exit (obstack_exit_failure);
422 }
423
424 #if 0
425 /* These are now turned off because the applications do not use it
426 and it uses bcopy via obstack_grow, which causes trouble on sysV. */
427
428 /* Now define the functional versions of the obstack macros.
429 Define them to simply use the corresponding macros to do the job. */
430
431 /* The function names appear in parentheses in order to prevent
432 the macro-definitions of the names from being expanded there. */
433
434 POINTER (obstack_base) (struct obstack *obstack)
435 {
436 return obstack_base (obstack);
437 }
438
439 POINTER (obstack_next_free) (struct obstack *obstack)
440 {
441 return obstack_next_free (obstack);
442 }
443
444 int (obstack_object_size) (struct obstack *obstack)
445 {
446 return obstack_object_size (obstack);
447 }
448
449 int (obstack_room) (struct obstack *obstack)
450 {
451 return obstack_room (obstack);
452 }
453
454 int (obstack_make_room) (struct obstack *obstack, int length)
455 {
456 return obstack_make_room (obstack, length);
457 }
458
459 void (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
460 {
461 obstack_grow (obstack, pointer, length);
462 }
463
464 void (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
465 {
466 obstack_grow0 (obstack, pointer, length);
467 }
468
469 void (obstack_1grow) (struct obstack *obstack, int character)
470 {
471 obstack_1grow (obstack, character);
472 }
473
474 void (obstack_blank) (struct obstack *obstack, int length)
475 {
476 obstack_blank (obstack, length);
477 }
478
479 void (obstack_1grow_fast) (struct obstack *obstack, int character)
480 {
481 obstack_1grow_fast (obstack, character);
482 }
483
484 void (obstack_blank_fast) (struct obstack *obstack, int length)
485 {
486 obstack_blank_fast (obstack, length);
487 }
488
489 POINTER (obstack_finish) (struct obstack *obstack)
490 {
491 return obstack_finish (obstack);
492 }
493
494 POINTER (obstack_alloc) (struct obstack *obstack, int length)
495 {
496 return obstack_alloc (obstack, length);
497 }
498
499 POINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
500 {
501 return obstack_copy (obstack, pointer, length);
502 }
503
504 POINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
505 {
506 return obstack_copy0 (obstack, pointer, length);
507 }
508
509 #endif /* 0 */
510
511 #endif /* !ELIDE_CODE */
512