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