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