Mercurial > hg > CbC > CbC_gcc
comparison include/obstack.h @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* obstack.h - object stack macros | |
2 Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, | |
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 | |
4 Free Software Foundation, Inc. | |
5 | |
6 | |
7 NOTE: The canonical source of this file is maintained with the GNU C Library. | |
8 Bugs can be reported to bug-glibc@gnu.org. | |
9 | |
10 This program is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
12 Free Software Foundation; either version 2, or (at your option) any | |
13 later version. | |
14 | |
15 This program is distributed in the hope that it will be useful, | |
16 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 GNU General Public License for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with this program; if not, write to the Free Software | |
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, | |
23 USA. */ | |
24 | |
25 /* Summary: | |
26 | |
27 All the apparent functions defined here are macros. The idea | |
28 is that you would use these pre-tested macros to solve a | |
29 very specific set of problems, and they would run fast. | |
30 Caution: no side-effects in arguments please!! They may be | |
31 evaluated MANY times!! | |
32 | |
33 These macros operate a stack of objects. Each object starts life | |
34 small, and may grow to maturity. (Consider building a word syllable | |
35 by syllable.) An object can move while it is growing. Once it has | |
36 been "finished" it never changes address again. So the "top of the | |
37 stack" is typically an immature growing object, while the rest of the | |
38 stack is of mature, fixed size and fixed address objects. | |
39 | |
40 These routines grab large chunks of memory, using a function you | |
41 supply, called `obstack_chunk_alloc'. On occasion, they free chunks, | |
42 by calling `obstack_chunk_free'. You must define them and declare | |
43 them before using any obstack macros. | |
44 | |
45 Each independent stack is represented by a `struct obstack'. | |
46 Each of the obstack macros expects a pointer to such a structure | |
47 as the first argument. | |
48 | |
49 One motivation for this package is the problem of growing char strings | |
50 in symbol tables. Unless you are "fascist pig with a read-only mind" | |
51 --Gosper's immortal quote from HAKMEM item 154, out of context--you | |
52 would not like to put any arbitrary upper limit on the length of your | |
53 symbols. | |
54 | |
55 In practice this often means you will build many short symbols and a | |
56 few long symbols. At the time you are reading a symbol you don't know | |
57 how long it is. One traditional method is to read a symbol into a | |
58 buffer, realloc()ating the buffer every time you try to read a symbol | |
59 that is longer than the buffer. This is beaut, but you still will | |
60 want to copy the symbol from the buffer to a more permanent | |
61 symbol-table entry say about half the time. | |
62 | |
63 With obstacks, you can work differently. Use one obstack for all symbol | |
64 names. As you read a symbol, grow the name in the obstack gradually. | |
65 When the name is complete, finalize it. Then, if the symbol exists already, | |
66 free the newly read name. | |
67 | |
68 The way we do this is to take a large chunk, allocating memory from | |
69 low addresses. When you want to build a symbol in the chunk you just | |
70 add chars above the current "high water mark" in the chunk. When you | |
71 have finished adding chars, because you got to the end of the symbol, | |
72 you know how long the chars are, and you can create a new object. | |
73 Mostly the chars will not burst over the highest address of the chunk, | |
74 because you would typically expect a chunk to be (say) 100 times as | |
75 long as an average object. | |
76 | |
77 In case that isn't clear, when we have enough chars to make up | |
78 the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) | |
79 so we just point to it where it lies. No moving of chars is | |
80 needed and this is the second win: potentially long strings need | |
81 never be explicitly shuffled. Once an object is formed, it does not | |
82 change its address during its lifetime. | |
83 | |
84 When the chars burst over a chunk boundary, we allocate a larger | |
85 chunk, and then copy the partly formed object from the end of the old | |
86 chunk to the beginning of the new larger chunk. We then carry on | |
87 accreting characters to the end of the object as we normally would. | |
88 | |
89 A special macro is provided to add a single char at a time to a | |
90 growing object. This allows the use of register variables, which | |
91 break the ordinary 'growth' macro. | |
92 | |
93 Summary: | |
94 We allocate large chunks. | |
95 We carve out one object at a time from the current chunk. | |
96 Once carved, an object never moves. | |
97 We are free to append data of any size to the currently | |
98 growing object. | |
99 Exactly one object is growing in an obstack at any one time. | |
100 You can run one obstack per control block. | |
101 You may have as many control blocks as you dare. | |
102 Because of the way we do it, you can `unwind' an obstack | |
103 back to a previous state. (You may remove objects much | |
104 as you would with a stack.) | |
105 */ | |
106 | |
107 | |
108 /* Don't do the contents of this file more than once. */ | |
109 | |
110 #ifndef _OBSTACK_H | |
111 #define _OBSTACK_H 1 | |
112 | |
113 #ifdef __cplusplus | |
114 extern "C" { | |
115 #endif | |
116 | |
117 /* We use subtraction of (char *) 0 instead of casting to int | |
118 because on word-addressable machines a simple cast to int | |
119 may ignore the byte-within-word field of the pointer. */ | |
120 | |
121 #ifndef __PTR_TO_INT | |
122 # define __PTR_TO_INT(P) ((P) - (char *) 0) | |
123 #endif | |
124 | |
125 #ifndef __INT_TO_PTR | |
126 # define __INT_TO_PTR(P) ((P) + (char *) 0) | |
127 #endif | |
128 | |
129 /* We need the type of the resulting object. If __PTRDIFF_TYPE__ is | |
130 defined, as with GNU C, use that; that way we don't pollute the | |
131 namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is | |
132 available, include it and use ptrdiff_t. In traditional C, long is | |
133 the best that we can do. */ | |
134 | |
135 #ifdef __PTRDIFF_TYPE__ | |
136 # define PTR_INT_TYPE __PTRDIFF_TYPE__ | |
137 #else | |
138 # ifdef HAVE_STDDEF_H | |
139 # include <stddef.h> | |
140 # define PTR_INT_TYPE ptrdiff_t | |
141 # else | |
142 # define PTR_INT_TYPE long | |
143 # endif | |
144 #endif | |
145 | |
146 #if defined _LIBC || defined HAVE_STRING_H | |
147 # include <string.h> | |
148 # define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N)) | |
149 #else | |
150 # ifdef memcpy | |
151 # define _obstack_memcpy(To, From, N) memcpy ((To), (char *)(From), (N)) | |
152 # else | |
153 # define _obstack_memcpy(To, From, N) bcopy ((char *)(From), (To), (N)) | |
154 # endif | |
155 #endif | |
156 | |
157 struct _obstack_chunk /* Lives at front of each chunk. */ | |
158 { | |
159 char *limit; /* 1 past end of this chunk */ | |
160 struct _obstack_chunk *prev; /* address of prior chunk or NULL */ | |
161 char contents[4]; /* objects begin here */ | |
162 }; | |
163 | |
164 struct obstack /* control current object in current chunk */ | |
165 { | |
166 long chunk_size; /* preferred size to allocate chunks in */ | |
167 struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ | |
168 char *object_base; /* address of object we are building */ | |
169 char *next_free; /* where to add next char to current object */ | |
170 char *chunk_limit; /* address of char after current chunk */ | |
171 PTR_INT_TYPE temp; /* Temporary for some macros. */ | |
172 int alignment_mask; /* Mask of alignment for each object. */ | |
173 /* These prototypes vary based on `use_extra_arg', and we use | |
174 casts to the prototypeless function type in all assignments, | |
175 but having prototypes here quiets -Wstrict-prototypes. */ | |
176 struct _obstack_chunk *(*chunkfun) (void *, long); | |
177 void (*freefun) (void *, struct _obstack_chunk *); | |
178 void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ | |
179 unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ | |
180 unsigned maybe_empty_object:1;/* There is a possibility that the current | |
181 chunk contains a zero-length object. This | |
182 prevents freeing the chunk if we allocate | |
183 a bigger chunk to replace it. */ | |
184 unsigned alloc_failed:1; /* No longer used, as we now call the failed | |
185 handler on error, but retained for binary | |
186 compatibility. */ | |
187 }; | |
188 | |
189 /* Declare the external functions we use; they are in obstack.c. */ | |
190 | |
191 extern void _obstack_newchunk (struct obstack *, int); | |
192 extern void _obstack_free (struct obstack *, void *); | |
193 extern int _obstack_begin (struct obstack *, int, int, | |
194 void *(*) (long), void (*) (void *)); | |
195 extern int _obstack_begin_1 (struct obstack *, int, int, | |
196 void *(*) (void *, long), | |
197 void (*) (void *, void *), void *); | |
198 extern int _obstack_memory_used (struct obstack *); | |
199 | |
200 /* Do the function-declarations after the structs | |
201 but before defining the macros. */ | |
202 | |
203 void obstack_init (struct obstack *obstack); | |
204 | |
205 void * obstack_alloc (struct obstack *obstack, int size); | |
206 | |
207 void * obstack_copy (struct obstack *obstack, void *address, int size); | |
208 void * obstack_copy0 (struct obstack *obstack, void *address, int size); | |
209 | |
210 void obstack_free (struct obstack *obstack, void *block); | |
211 | |
212 void obstack_blank (struct obstack *obstack, int size); | |
213 | |
214 void obstack_grow (struct obstack *obstack, void *data, int size); | |
215 void obstack_grow0 (struct obstack *obstack, void *data, int size); | |
216 | |
217 void obstack_1grow (struct obstack *obstack, int data_char); | |
218 void obstack_ptr_grow (struct obstack *obstack, void *data); | |
219 void obstack_int_grow (struct obstack *obstack, int data); | |
220 | |
221 void * obstack_finish (struct obstack *obstack); | |
222 | |
223 int obstack_object_size (struct obstack *obstack); | |
224 | |
225 int obstack_room (struct obstack *obstack); | |
226 void obstack_make_room (struct obstack *obstack, int size); | |
227 void obstack_1grow_fast (struct obstack *obstack, int data_char); | |
228 void obstack_ptr_grow_fast (struct obstack *obstack, void *data); | |
229 void obstack_int_grow_fast (struct obstack *obstack, int data); | |
230 void obstack_blank_fast (struct obstack *obstack, int size); | |
231 | |
232 void * obstack_base (struct obstack *obstack); | |
233 void * obstack_next_free (struct obstack *obstack); | |
234 int obstack_alignment_mask (struct obstack *obstack); | |
235 int obstack_chunk_size (struct obstack *obstack); | |
236 int obstack_memory_used (struct obstack *obstack); | |
237 | |
238 /* Error handler called when `obstack_chunk_alloc' failed to allocate | |
239 more memory. This can be set to a user defined function. The | |
240 default action is to print a message and abort. */ | |
241 extern void (*obstack_alloc_failed_handler) (void); | |
242 | |
243 /* Exit value used when `print_and_abort' is used. */ | |
244 extern int obstack_exit_failure; | |
245 | |
246 /* Pointer to beginning of object being allocated or to be allocated next. | |
247 Note that this might not be the final address of the object | |
248 because a new chunk might be needed to hold the final size. */ | |
249 | |
250 #define obstack_base(h) ((h)->object_base) | |
251 | |
252 /* Size for allocating ordinary chunks. */ | |
253 | |
254 #define obstack_chunk_size(h) ((h)->chunk_size) | |
255 | |
256 /* Pointer to next byte not yet allocated in current chunk. */ | |
257 | |
258 #define obstack_next_free(h) ((h)->next_free) | |
259 | |
260 /* Mask specifying low bits that should be clear in address of an object. */ | |
261 | |
262 #define obstack_alignment_mask(h) ((h)->alignment_mask) | |
263 | |
264 /* To prevent prototype warnings provide complete argument list in | |
265 standard C version. */ | |
266 # define obstack_init(h) \ | |
267 _obstack_begin ((h), 0, 0, \ | |
268 (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) | |
269 | |
270 # define obstack_begin(h, size) \ | |
271 _obstack_begin ((h), (size), 0, \ | |
272 (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free) | |
273 | |
274 # define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ | |
275 _obstack_begin ((h), (size), (alignment), \ | |
276 (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun)) | |
277 | |
278 # define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ | |
279 _obstack_begin_1 ((h), (size), (alignment), \ | |
280 (void *(*) (void *, long)) (chunkfun), \ | |
281 (void (*) (void *, void *)) (freefun), (arg)) | |
282 | |
283 # define obstack_chunkfun(h, newchunkfun) \ | |
284 ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) | |
285 | |
286 # define obstack_freefun(h, newfreefun) \ | |
287 ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) | |
288 | |
289 #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) | |
290 | |
291 #define obstack_blank_fast(h,n) ((h)->next_free += (n)) | |
292 | |
293 #define obstack_memory_used(h) _obstack_memory_used (h) | |
294 | |
295 #if defined __GNUC__ && defined __STDC__ && __STDC__ | |
296 /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and | |
297 does not implement __extension__. But that compiler doesn't define | |
298 __GNUC_MINOR__. */ | |
299 # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) | |
300 # define __extension__ | |
301 # endif | |
302 | |
303 /* For GNU C, if not -traditional, | |
304 we can define these macros to compute all args only once | |
305 without using a global variable. | |
306 Also, we can avoid using the `temp' slot, to make faster code. */ | |
307 | |
308 # define obstack_object_size(OBSTACK) \ | |
309 __extension__ \ | |
310 ({ struct obstack *__o = (OBSTACK); \ | |
311 (unsigned) (__o->next_free - __o->object_base); }) | |
312 | |
313 # define obstack_room(OBSTACK) \ | |
314 __extension__ \ | |
315 ({ struct obstack *__o = (OBSTACK); \ | |
316 (unsigned) (__o->chunk_limit - __o->next_free); }) | |
317 | |
318 # define obstack_make_room(OBSTACK,length) \ | |
319 __extension__ \ | |
320 ({ struct obstack *__o = (OBSTACK); \ | |
321 int __len = (length); \ | |
322 if (__o->chunk_limit - __o->next_free < __len) \ | |
323 _obstack_newchunk (__o, __len); \ | |
324 (void) 0; }) | |
325 | |
326 # define obstack_empty_p(OBSTACK) \ | |
327 __extension__ \ | |
328 ({ struct obstack *__o = (OBSTACK); \ | |
329 (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); }) | |
330 | |
331 # define obstack_grow(OBSTACK,where,length) \ | |
332 __extension__ \ | |
333 ({ struct obstack *__o = (OBSTACK); \ | |
334 int __len = (length); \ | |
335 if (__o->next_free + __len > __o->chunk_limit) \ | |
336 _obstack_newchunk (__o, __len); \ | |
337 _obstack_memcpy (__o->next_free, (where), __len); \ | |
338 __o->next_free += __len; \ | |
339 (void) 0; }) | |
340 | |
341 # define obstack_grow0(OBSTACK,where,length) \ | |
342 __extension__ \ | |
343 ({ struct obstack *__o = (OBSTACK); \ | |
344 int __len = (length); \ | |
345 if (__o->next_free + __len + 1 > __o->chunk_limit) \ | |
346 _obstack_newchunk (__o, __len + 1); \ | |
347 _obstack_memcpy (__o->next_free, (where), __len); \ | |
348 __o->next_free += __len; \ | |
349 *(__o->next_free)++ = 0; \ | |
350 (void) 0; }) | |
351 | |
352 # define obstack_1grow(OBSTACK,datum) \ | |
353 __extension__ \ | |
354 ({ struct obstack *__o = (OBSTACK); \ | |
355 if (__o->next_free + 1 > __o->chunk_limit) \ | |
356 _obstack_newchunk (__o, 1); \ | |
357 obstack_1grow_fast (__o, datum); \ | |
358 (void) 0; }) | |
359 | |
360 /* These assume that the obstack alignment is good enough for pointers or ints, | |
361 and that the data added so far to the current object | |
362 shares that much alignment. */ | |
363 | |
364 # define obstack_ptr_grow(OBSTACK,datum) \ | |
365 __extension__ \ | |
366 ({ struct obstack *__o = (OBSTACK); \ | |
367 if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ | |
368 _obstack_newchunk (__o, sizeof (void *)); \ | |
369 obstack_ptr_grow_fast (__o, datum); }) | |
370 | |
371 # define obstack_int_grow(OBSTACK,datum) \ | |
372 __extension__ \ | |
373 ({ struct obstack *__o = (OBSTACK); \ | |
374 if (__o->next_free + sizeof (int) > __o->chunk_limit) \ | |
375 _obstack_newchunk (__o, sizeof (int)); \ | |
376 obstack_int_grow_fast (__o, datum); }) | |
377 | |
378 # define obstack_ptr_grow_fast(OBSTACK,aptr) \ | |
379 __extension__ \ | |
380 ({ struct obstack *__o1 = (OBSTACK); \ | |
381 *(const void **) __o1->next_free = (aptr); \ | |
382 __o1->next_free += sizeof (const void *); \ | |
383 (void) 0; }) | |
384 | |
385 # define obstack_int_grow_fast(OBSTACK,aint) \ | |
386 __extension__ \ | |
387 ({ struct obstack *__o1 = (OBSTACK); \ | |
388 *(int *) __o1->next_free = (aint); \ | |
389 __o1->next_free += sizeof (int); \ | |
390 (void) 0; }) | |
391 | |
392 # define obstack_blank(OBSTACK,length) \ | |
393 __extension__ \ | |
394 ({ struct obstack *__o = (OBSTACK); \ | |
395 int __len = (length); \ | |
396 if (__o->chunk_limit - __o->next_free < __len) \ | |
397 _obstack_newchunk (__o, __len); \ | |
398 obstack_blank_fast (__o, __len); \ | |
399 (void) 0; }) | |
400 | |
401 # define obstack_alloc(OBSTACK,length) \ | |
402 __extension__ \ | |
403 ({ struct obstack *__h = (OBSTACK); \ | |
404 obstack_blank (__h, (length)); \ | |
405 obstack_finish (__h); }) | |
406 | |
407 # define obstack_copy(OBSTACK,where,length) \ | |
408 __extension__ \ | |
409 ({ struct obstack *__h = (OBSTACK); \ | |
410 obstack_grow (__h, (where), (length)); \ | |
411 obstack_finish (__h); }) | |
412 | |
413 # define obstack_copy0(OBSTACK,where,length) \ | |
414 __extension__ \ | |
415 ({ struct obstack *__h = (OBSTACK); \ | |
416 obstack_grow0 (__h, (where), (length)); \ | |
417 obstack_finish (__h); }) | |
418 | |
419 /* The local variable is named __o1 to avoid a name conflict | |
420 when obstack_blank is called. */ | |
421 # define obstack_finish(OBSTACK) \ | |
422 __extension__ \ | |
423 ({ struct obstack *__o1 = (OBSTACK); \ | |
424 void *value; \ | |
425 value = (void *) __o1->object_base; \ | |
426 if (__o1->next_free == value) \ | |
427 __o1->maybe_empty_object = 1; \ | |
428 __o1->next_free \ | |
429 = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ | |
430 & ~ (__o1->alignment_mask)); \ | |
431 if (__o1->next_free - (char *)__o1->chunk \ | |
432 > __o1->chunk_limit - (char *)__o1->chunk) \ | |
433 __o1->next_free = __o1->chunk_limit; \ | |
434 __o1->object_base = __o1->next_free; \ | |
435 value; }) | |
436 | |
437 # define obstack_free(OBSTACK, OBJ) \ | |
438 __extension__ \ | |
439 ({ struct obstack *__o = (OBSTACK); \ | |
440 void *__obj = (void *) (OBJ); \ | |
441 if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ | |
442 __o->next_free = __o->object_base = (char *) __obj; \ | |
443 else (obstack_free) (__o, __obj); }) | |
444 | |
445 #else /* not __GNUC__ or not __STDC__ */ | |
446 | |
447 # define obstack_object_size(h) \ | |
448 (unsigned) ((h)->next_free - (h)->object_base) | |
449 | |
450 # define obstack_room(h) \ | |
451 (unsigned) ((h)->chunk_limit - (h)->next_free) | |
452 | |
453 # define obstack_empty_p(h) \ | |
454 ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0) | |
455 | |
456 /* Note that the call to _obstack_newchunk is enclosed in (..., 0) | |
457 so that we can avoid having void expressions | |
458 in the arms of the conditional expression. | |
459 Casting the third operand to void was tried before, | |
460 but some compilers won't accept it. */ | |
461 | |
462 # define obstack_make_room(h,length) \ | |
463 ( (h)->temp = (length), \ | |
464 (((h)->next_free + (h)->temp > (h)->chunk_limit) \ | |
465 ? (_obstack_newchunk ((h), (h)->temp), 0) : 0)) | |
466 | |
467 # define obstack_grow(h,where,length) \ | |
468 ( (h)->temp = (length), \ | |
469 (((h)->next_free + (h)->temp > (h)->chunk_limit) \ | |
470 ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ | |
471 _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ | |
472 (h)->next_free += (h)->temp) | |
473 | |
474 # define obstack_grow0(h,where,length) \ | |
475 ( (h)->temp = (length), \ | |
476 (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ | |
477 ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ | |
478 _obstack_memcpy ((h)->next_free, (where), (h)->temp), \ | |
479 (h)->next_free += (h)->temp, \ | |
480 *((h)->next_free)++ = 0) | |
481 | |
482 # define obstack_1grow(h,datum) \ | |
483 ( (((h)->next_free + 1 > (h)->chunk_limit) \ | |
484 ? (_obstack_newchunk ((h), 1), 0) : 0), \ | |
485 obstack_1grow_fast (h, datum)) | |
486 | |
487 # define obstack_ptr_grow(h,datum) \ | |
488 ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ | |
489 ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ | |
490 obstack_ptr_grow_fast (h, datum)) | |
491 | |
492 # define obstack_int_grow(h,datum) \ | |
493 ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ | |
494 ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ | |
495 obstack_int_grow_fast (h, datum)) | |
496 | |
497 # define obstack_ptr_grow_fast(h,aptr) \ | |
498 (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) | |
499 | |
500 # define obstack_int_grow_fast(h,aint) \ | |
501 (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) | |
502 | |
503 # define obstack_blank(h,length) \ | |
504 ( (h)->temp = (length), \ | |
505 (((h)->chunk_limit - (h)->next_free < (h)->temp) \ | |
506 ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ | |
507 obstack_blank_fast (h, (h)->temp)) | |
508 | |
509 # define obstack_alloc(h,length) \ | |
510 (obstack_blank ((h), (length)), obstack_finish ((h))) | |
511 | |
512 # define obstack_copy(h,where,length) \ | |
513 (obstack_grow ((h), (where), (length)), obstack_finish ((h))) | |
514 | |
515 # define obstack_copy0(h,where,length) \ | |
516 (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) | |
517 | |
518 # define obstack_finish(h) \ | |
519 ( ((h)->next_free == (h)->object_base \ | |
520 ? (((h)->maybe_empty_object = 1), 0) \ | |
521 : 0), \ | |
522 (h)->temp = __PTR_TO_INT ((h)->object_base), \ | |
523 (h)->next_free \ | |
524 = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ | |
525 & ~ ((h)->alignment_mask)), \ | |
526 (((h)->next_free - (char *) (h)->chunk \ | |
527 > (h)->chunk_limit - (char *) (h)->chunk) \ | |
528 ? ((h)->next_free = (h)->chunk_limit) : 0), \ | |
529 (h)->object_base = (h)->next_free, \ | |
530 (void *) __INT_TO_PTR ((h)->temp)) | |
531 | |
532 # define obstack_free(h,obj) \ | |
533 ( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \ | |
534 (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ | |
535 ? (int) ((h)->next_free = (h)->object_base \ | |
536 = (h)->temp + (char *) (h)->chunk) \ | |
537 : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) | |
538 | |
539 #endif /* not __GNUC__ or not __STDC__ */ | |
540 | |
541 #ifdef __cplusplus | |
542 } /* C++ */ | |
543 #endif | |
544 | |
545 #endif /* obstack.h */ |