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