Don't use prototypes for vfprintf_filtered(). Someday we'll get prototypes of
[external/binutils.git] / bfd / obstack.c
1 /* obstack.c - subroutines used implicitly by object stack macros
2    Copyright (C) 1988 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 1, 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 #include <ansidecl.h>
18 #include <sysdep.h>
19 #include "obstack.h"
20
21
22 /* Determine default alignment.  */
23 struct fooalign {char x; double d;};
24 #define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
25 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
26    But in fact it might be less smart and round addresses to as much as
27    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
28 union fooround {long x; double d;};
29 #define DEFAULT_ROUNDING (sizeof (union fooround))
30
31 /* When we copy a long block of data, this is the unit to do it with.
32    On some machines, copying successive ints does not work;
33    in such a case, redefine COPYING_UNIT to `long' (if that works)
34    or `char' as a last resort.  */
35 #ifndef COPYING_UNIT
36 #define COPYING_UNIT int
37 #endif
38
39 /* The non-GNU-C macros copy the obstack into this global variable
40    to avoid multiple evaluation.  */
41
42 struct obstack *_obstack;
43 \f
44 /* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
45    Objects start on multiples of ALIGNMENT (0 means use default).
46    CHUNKFUN is the function to use to allocate chunks,
47    and FREEFUN the function to free them.  */
48
49 void DEFUN(_obstack_begin,(h, size, alignment, chunkfun, freefun),
50            struct obstack *h AND
51            int size AND
52            int alignment AND
53            PTR (*chunkfun) () AND
54            void (*freefun) ())
55 {
56   register struct _obstack_chunk* chunk; /* points to new chunk */
57
58   if (alignment == 0)
59     alignment = DEFAULT_ALIGNMENT;
60   if (size == 0)
61     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
62     {
63       /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
64          Use the values for range checking, because if range checking is off,
65          the extra bytes won't be missed terribly, but if range checking is on
66          and we used a larger request, a whole extra 4096 bytes would be
67          allocated.
68
69          These number are irrelevant to the new GNU malloc.  I suspect it is
70          less sensitive to the size of the request.  */
71       int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
72                     + 4 + DEFAULT_ROUNDING - 1)
73                    & ~(DEFAULT_ROUNDING - 1));
74       size = 4096 - extra;
75     }
76
77   h->chunkfun = chunkfun;
78   h->freefun = freefun;
79   h->chunk_size = size;
80   h->alignment_mask = alignment - 1;
81
82   chunk = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (h->chunk_size);
83   h->next_free = h->object_base = chunk->contents;
84   h->chunk_limit = chunk->limit
85    = (char *) chunk + h->chunk_size;
86   chunk->prev = 0;
87 }
88
89 /* Allocate a new current chunk for the obstack *H
90    on the assumption that LENGTH bytes need to be added
91    to the current object, or a new object of length LENGTH allocated.
92    Copies any partial object from the end of the old chunk
93    to the beginning of the new one.  
94
95    The function must be "int" so it can be used in non-ANSI C
96    compilers in a : expression.  */
97
98 int
99 DEFUN(_obstack_newchunk,(h, length),
100       struct obstack *h AND
101       int length)
102 {
103   register struct _obstack_chunk*       old_chunk = h->chunk;
104   register struct _obstack_chunk*       new_chunk;
105   register long new_size;
106   register int obj_size = h->next_free - h->object_base;
107   register int i;
108   int already;
109
110   /* Compute size for new chunk.  */
111   new_size = (obj_size + length) + (obj_size >> 3) + 100;
112   if (new_size < h->chunk_size)
113     new_size = h->chunk_size;
114
115   /* Allocate and initialize the new chunk.  */
116   new_chunk = h->chunk = (struct _obstack_chunk *)(*h->chunkfun) (new_size);
117   new_chunk->prev = old_chunk;
118   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
119
120   /* Move the existing object to the new chunk.
121      Word at a time is fast and is safe if the object
122      is sufficiently aligned.  */
123   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
124     {
125       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
126            i >= 0; i--)
127         ((COPYING_UNIT *)new_chunk->contents)[i]
128           = ((COPYING_UNIT *)h->object_base)[i];
129       /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
130          but that can cross a page boundary on a machine
131          which does not do strict alignment for COPYING_UNITS.  */
132       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
133     }
134   else
135     already = 0;
136   /* Copy remaining bytes one by one.  */
137   for (i = already; i < obj_size; i++)
138     new_chunk->contents[i] = h->object_base[i];
139
140   h->object_base = new_chunk->contents;
141   h->next_free = h->object_base + obj_size;
142 return 0;
143 }
144
145 /* Return nonzero if object OBJ has been allocated from obstack H.
146    This is here for debugging.
147    If you use it in a program, you are probably losing.  */
148
149 int
150 DEFUN(_obstack_allocated_p, (h, obj), 
151       struct obstack *h AND
152       PTR obj)
153 {
154   register struct _obstack_chunk*  lp; /* below addr of any objects in this chunk */
155   register struct _obstack_chunk*  plp; /* point to previous chunk if any */
156
157   lp = (h)->chunk;
158   while (lp != 0 && ((PTR)lp > obj || (PTR)(lp)->limit < obj))
159       {
160         plp = lp -> prev;
161         lp = plp;
162       }
163   return lp != 0;
164 }
165
166 /* Free objects in obstack H, including OBJ and everything allocate
167    more recently than OBJ.  If OBJ is zero, free everything in H.  */
168
169 #ifdef __STDC__
170 #undef obstack_free
171 void
172 obstack_free (struct obstack *h, PTR obj)
173 #else
174 int
175 _obstack_free (h, obj)
176      struct obstack *h;
177      PTR obj;
178 #endif
179 {
180   register struct _obstack_chunk*  lp;  /* below addr of any objects in this chunk */
181   register struct _obstack_chunk*  plp; /* point to previous chunk if any */
182
183   lp = (h)->chunk;
184   /* We use >= because there cannot be an object at the beginning of a chunk.
185      But there can be an empty object at that address
186      at the end of another chunk.  */
187   while (lp != 0 && ((PTR)lp >= obj || (PTR)(lp)->limit < obj))
188     {
189       plp = lp -> prev;
190       (*h->freefun) ((PTR) lp);
191       lp = plp;
192     }
193   if (lp)
194     {
195       (h)->object_base = (h)->next_free = (char *)(obj);
196       (h)->chunk_limit = lp->limit;
197       (h)->chunk = lp;
198     }
199   else if (obj != 0)
200     /* obj is not in any of the chunks! */
201     abort ();
202 }
203
204 /* Let same .o link with output of gcc and other compilers.  */
205
206 #ifdef __STDC__
207 int
208 _obstack_free (h, obj)
209      struct obstack *h;
210      PTR obj;
211 {
212   obstack_free (h, obj);
213   return 0;
214 }
215 #endif
216 \f
217 /* #if 0 */
218 /* These are now turned off because the applications do not use it
219    and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
220
221 /* Now define the functional versions of the obstack macros.
222    Define them to simply use the corresponding macros to do the job.  */
223
224 #ifdef __STDC__
225 /* These function definitions do not work with non-ANSI preprocessors;
226    they won't pass through the macro names in parentheses.  */
227
228 /* The function names appear in parentheses in order to prevent
229    the macro-definitions of the names from being expanded there.  */
230
231 PTR (obstack_base) (obstack)
232      struct obstack *obstack;
233 {
234   return obstack_base (obstack);
235 }
236
237 PTR (obstack_next_free) (obstack)
238      struct obstack *obstack;
239 {
240   return obstack_next_free (obstack);
241 }
242
243 int (obstack_object_size) (obstack)
244      struct obstack *obstack;
245 {
246   return obstack_object_size (obstack);
247 }
248
249 int (obstack_room) (obstack)
250      struct obstack *obstack;
251 {
252   return obstack_room (obstack);
253 }
254
255 void (obstack_grow) (obstack, ptr, length)
256      struct obstack *obstack;
257      PTR ptr;
258      int length;
259 {
260 (void)  obstack_grow (obstack, ptr, length);
261 }
262
263 void (obstack_grow0) (obstack, ptr, length)
264      struct obstack *obstack;
265      PTR ptr;
266      int length;
267 {
268 (void)  obstack_grow0 (obstack, ptr, length);
269 }
270
271 void (obstack_1grow) (obstack, character)
272      struct obstack *obstack;
273      int character;
274 {
275 (void)  obstack_1grow (obstack, character);
276 }
277
278 void (obstack_blank) (obstack, length)
279      struct obstack *obstack;
280      int length;
281 {
282 (void)  obstack_blank (obstack, length);
283 }
284
285 void (obstack_1grow_fast) (obstack, character)
286      struct obstack *obstack;
287      int character;
288 {
289   obstack_1grow_fast (obstack, character);
290 }
291
292 void (obstack_blank_fast) (obstack, length)
293      struct obstack *obstack;
294      int length;
295 {
296   obstack_blank_fast (obstack, length);
297 }
298
299 PTR (obstack_finish) (obstack)
300      struct obstack *obstack;
301 {
302   return obstack_finish (obstack);
303 }
304
305 PTR (obstack_alloc) (obstack, length)
306      struct obstack *obstack;
307      int length;
308 {
309   return obstack_alloc (obstack, length);
310 }
311
312 PTR (obstack_copy) (obstack, ptr, length)
313      struct obstack *obstack;
314      PTR ptr;
315      int length;
316 {
317   return obstack_copy (obstack, ptr, length);
318 }
319
320 PTR (obstack_copy0) (obstack, ptr, length)
321      struct obstack *obstack;
322      PTR ptr;
323      int length;
324 {
325   return obstack_copy0 (obstack, ptr, length);
326 }
327
328 #endif /* __STDC__ */
329
330