133
129
relative to B. Otherwise, use the faster strategy of computing the
134
130
alignment relative to 0. */
136
#define __PTR_ALIGN(B, P, A) \
132
#define __PTR_ALIGN(B, P, A) \
137
133
__BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
140
136
#include <string.h>
142
struct _obstack_chunk /* Lives at front of each chunk. */
142
struct _obstack_chunk /* Lives at front of each chunk. */
144
char *limit; /* 1 past end of this chunk */
145
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
146
char contents[4]; /* objects begin here */
144
char *limit; /* 1 past end of this chunk */
145
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
146
char contents[4]; /* objects begin here */
149
struct obstack /* control current object in current chunk */
149
struct obstack /* control current object in current chunk */
151
long chunk_size; /* preferred size to allocate chunks in */
152
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
153
char *object_base; /* address of object we are building */
154
char *next_free; /* where to add next char to current object */
155
char *chunk_limit; /* address of char after current chunk */
151
long chunk_size; /* preferred size to allocate chunks in */
152
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
153
char *object_base; /* address of object we are building */
154
char *next_free; /* where to add next char to current object */
155
char *chunk_limit; /* address of char after current chunk */
158
158
PTR_INT_TYPE tempint;
160
} temp; /* Temporary for some macros. */
161
int alignment_mask; /* Mask of alignment for each object. */
160
} temp; /* Temporary for some macros. */
161
int alignment_mask; /* Mask of alignment for each object. */
162
162
/* These prototypes vary based on `use_extra_arg', and we use
163
163
casts to the prototypeless function type in all assignments,
164
164
but having prototypes here quiets -Wstrict-prototypes. */
165
165
struct _obstack_chunk *(*chunkfun) (void *, long);
166
166
void (*freefun) (void *, struct _obstack_chunk *);
167
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
168
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
167
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
168
unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
169
169
unsigned maybe_empty_object:1;/* There is a possibility that the current
170
chunk contains a zero-length object. This
171
prevents freeing the chunk if we allocate
172
a bigger chunk to replace it. */
173
unsigned alloc_failed:1; /* No longer used, as we now call the failed
174
handler on error, but retained for binary
170
chunk contains a zero-length object. This
171
prevents freeing the chunk if we allocate
172
a bigger chunk to replace it. */
173
unsigned alloc_failed:1; /* No longer used, as we now call the failed
174
handler on error, but retained for binary
178
178
/* Declare the external functions we use; they are in obstack.c. */
180
180
extern void _obstack_newchunk (struct obstack *, int);
181
181
extern int _obstack_begin (struct obstack *, int, int,
182
void *(*) (long), void (*) (void *));
182
void *(*) (long), void (*) (void *));
183
183
extern int _obstack_begin_1 (struct obstack *, int, int,
184
void *(*) (void *, long),
185
void (*) (void *, void *), void *);
184
void *(*) (void *, long),
185
void (*) (void *, void *), void *);
186
186
extern int _obstack_memory_used (struct obstack *);
188
188
/* The default name of the function for freeing a chunk is 'obstack_free',
215
215
/* Pointer to next byte not yet allocated in current chunk. */
217
#define obstack_next_free(h) ((h)->next_free)
217
#define obstack_next_free(h) ((h)->next_free)
219
219
/* Mask specifying low bits that should be clear in address of an object. */
221
221
#define obstack_alignment_mask(h) ((h)->alignment_mask)
223
223
/* To prevent prototype warnings provide complete argument list. */
224
#define obstack_init(h) \
225
_obstack_begin ((h), 0, 0, \
226
(void *(*) (long)) obstack_chunk_alloc, \
227
(void (*) (void *)) obstack_chunk_free)
224
#define obstack_init(h) \
225
_obstack_begin ((h), 0, 0, \
226
(void *(*) (long)) obstack_chunk_alloc, \
227
(void (*) (void *)) obstack_chunk_free)
229
#define obstack_begin(h, size) \
230
_obstack_begin ((h), (size), 0, \
231
(void *(*) (long)) obstack_chunk_alloc, \
232
(void (*) (void *)) obstack_chunk_free)
229
#define obstack_begin(h, size) \
230
_obstack_begin ((h), (size), 0, \
231
(void *(*) (long)) obstack_chunk_alloc, \
232
(void (*) (void *)) obstack_chunk_free)
234
234
#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
235
_obstack_begin ((h), (size), (alignment), \
236
(void *(*) (long)) (chunkfun), \
237
(void (*) (void *)) (freefun))
235
_obstack_begin ((h), (size), (alignment), \
236
(void *(*) (long)) (chunkfun), \
237
(void (*) (void *)) (freefun))
239
239
#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
240
_obstack_begin_1 ((h), (size), (alignment), \
241
(void *(*) (void *, long)) (chunkfun), \
242
(void (*) (void *, void *)) (freefun), (arg))
240
_obstack_begin_1 ((h), (size), (alignment), \
241
(void *(*) (void *, long)) (chunkfun), \
242
(void (*) (void *, void *)) (freefun), (arg))
244
244
#define obstack_chunkfun(h, newchunkfun) \
245
245
((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
266
266
without using a global variable.
267
267
Also, we can avoid using the `temp' slot, to make faster code. */
269
# define obstack_object_size(OBSTACK) \
271
({ struct obstack const *__o = (OBSTACK); \
269
# define obstack_object_size(OBSTACK) \
271
({ struct obstack const *__o = (OBSTACK); \
272
272
(unsigned) (__o->next_free - __o->object_base); })
274
# define obstack_room(OBSTACK) \
276
({ struct obstack const *__o = (OBSTACK); \
274
# define obstack_room(OBSTACK) \
276
({ struct obstack const *__o = (OBSTACK); \
277
277
(unsigned) (__o->chunk_limit - __o->next_free); })
279
# define obstack_make_room(OBSTACK,length) \
281
({ struct obstack *__o = (OBSTACK); \
282
int __len = (length); \
283
if (__o->chunk_limit - __o->next_free < __len) \
284
_obstack_newchunk (__o, __len); \
287
# define obstack_empty_p(OBSTACK) \
289
({ struct obstack const *__o = (OBSTACK); \
290
(__o->chunk->prev == 0 \
291
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
292
__o->chunk->contents, \
293
__o->alignment_mask)); })
295
# define obstack_grow(OBSTACK,where,length) \
297
({ struct obstack *__o = (OBSTACK); \
298
int __len = (length); \
299
if (__o->next_free + __len > __o->chunk_limit) \
300
_obstack_newchunk (__o, __len); \
301
memcpy (__o->next_free, where, __len); \
302
__o->next_free += __len; \
305
# define obstack_grow0(OBSTACK,where,length) \
307
({ struct obstack *__o = (OBSTACK); \
308
int __len = (length); \
309
if (__o->next_free + __len + 1 > __o->chunk_limit) \
310
_obstack_newchunk (__o, __len + 1); \
311
memcpy (__o->next_free, where, __len); \
312
__o->next_free += __len; \
313
*(__o->next_free)++ = 0; \
316
# define obstack_1grow(OBSTACK,datum) \
318
({ struct obstack *__o = (OBSTACK); \
319
if (__o->next_free + 1 > __o->chunk_limit) \
320
_obstack_newchunk (__o, 1); \
321
obstack_1grow_fast (__o, datum); \
279
# define obstack_make_room(OBSTACK,length) \
281
({ struct obstack *__o = (OBSTACK); \
282
int __len = (length); \
283
if (__o->chunk_limit - __o->next_free < __len) \
284
_obstack_newchunk (__o, __len); \
287
# define obstack_empty_p(OBSTACK) \
289
({ struct obstack const *__o = (OBSTACK); \
290
(__o->chunk->prev == 0 \
291
&& __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
292
__o->chunk->contents, \
293
__o->alignment_mask)); })
295
# define obstack_grow(OBSTACK,where,length) \
297
({ struct obstack *__o = (OBSTACK); \
298
int __len = (length); \
299
if (__o->next_free + __len > __o->chunk_limit) \
300
_obstack_newchunk (__o, __len); \
301
memcpy (__o->next_free, where, __len); \
302
__o->next_free += __len; \
305
# define obstack_grow0(OBSTACK,where,length) \
307
({ struct obstack *__o = (OBSTACK); \
308
int __len = (length); \
309
if (__o->next_free + __len + 1 > __o->chunk_limit) \
310
_obstack_newchunk (__o, __len + 1); \
311
memcpy (__o->next_free, where, __len); \
312
__o->next_free += __len; \
313
*(__o->next_free)++ = 0; \
316
# define obstack_1grow(OBSTACK,datum) \
318
({ struct obstack *__o = (OBSTACK); \
319
if (__o->next_free + 1 > __o->chunk_limit) \
320
_obstack_newchunk (__o, 1); \
321
obstack_1grow_fast (__o, datum); \
324
324
/* These assume that the obstack alignment is good enough for pointers
325
325
or ints, and that the data added so far to the current object
326
326
shares that much alignment. */
328
# define obstack_ptr_grow(OBSTACK,datum) \
330
({ struct obstack *__o = (OBSTACK); \
331
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
332
_obstack_newchunk (__o, sizeof (void *)); \
333
obstack_ptr_grow_fast (__o, datum); }) \
328
# define obstack_ptr_grow(OBSTACK,datum) \
330
({ struct obstack *__o = (OBSTACK); \
331
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
332
_obstack_newchunk (__o, sizeof (void *)); \
333
obstack_ptr_grow_fast (__o, datum); }) \
335
# define obstack_int_grow(OBSTACK,datum) \
337
({ struct obstack *__o = (OBSTACK); \
338
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
339
_obstack_newchunk (__o, sizeof (int)); \
335
# define obstack_int_grow(OBSTACK,datum) \
337
({ struct obstack *__o = (OBSTACK); \
338
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
339
_obstack_newchunk (__o, sizeof (int)); \
340
340
obstack_int_grow_fast (__o, datum); })
342
# define obstack_ptr_grow_fast(OBSTACK,aptr) \
344
({ struct obstack *__o1 = (OBSTACK); \
345
*(const void **) __o1->next_free = (aptr); \
346
__o1->next_free += sizeof (const void *); \
349
# define obstack_int_grow_fast(OBSTACK,aint) \
351
({ struct obstack *__o1 = (OBSTACK); \
352
*(int *) __o1->next_free = (aint); \
353
__o1->next_free += sizeof (int); \
356
# define obstack_blank(OBSTACK,length) \
358
({ struct obstack *__o = (OBSTACK); \
359
int __len = (length); \
360
if (__o->chunk_limit - __o->next_free < __len) \
361
_obstack_newchunk (__o, __len); \
362
obstack_blank_fast (__o, __len); \
365
# define obstack_alloc(OBSTACK,length) \
367
({ struct obstack *__h = (OBSTACK); \
368
obstack_blank (__h, (length)); \
369
obstack_finish (__h); })
371
# define obstack_copy(OBSTACK,where,length) \
373
({ struct obstack *__h = (OBSTACK); \
374
obstack_grow (__h, (where), (length)); \
375
obstack_finish (__h); })
377
# define obstack_copy0(OBSTACK,where,length) \
379
({ struct obstack *__h = (OBSTACK); \
380
obstack_grow0 (__h, (where), (length)); \
342
# define obstack_ptr_grow_fast(OBSTACK,aptr) \
344
({ struct obstack *__o1 = (OBSTACK); \
345
*(const void **) __o1->next_free = (aptr); \
346
__o1->next_free += sizeof (const void *); \
349
# define obstack_int_grow_fast(OBSTACK,aint) \
351
({ struct obstack *__o1 = (OBSTACK); \
352
*(int *) __o1->next_free = (aint); \
353
__o1->next_free += sizeof (int); \
356
# define obstack_blank(OBSTACK,length) \
358
({ struct obstack *__o = (OBSTACK); \
359
int __len = (length); \
360
if (__o->chunk_limit - __o->next_free < __len) \
361
_obstack_newchunk (__o, __len); \
362
obstack_blank_fast (__o, __len); \
365
# define obstack_alloc(OBSTACK,length) \
367
({ struct obstack *__h = (OBSTACK); \
368
obstack_blank (__h, (length)); \
369
obstack_finish (__h); })
371
# define obstack_copy(OBSTACK,where,length) \
373
({ struct obstack *__h = (OBSTACK); \
374
obstack_grow (__h, (where), (length)); \
375
obstack_finish (__h); })
377
# define obstack_copy0(OBSTACK,where,length) \
379
({ struct obstack *__h = (OBSTACK); \
380
obstack_grow0 (__h, (where), (length)); \
381
381
obstack_finish (__h); })
383
383
/* The local variable is named __o1 to avoid a name conflict
384
384
when obstack_blank is called. */
385
# define obstack_finish(OBSTACK) \
387
({ struct obstack *__o1 = (OBSTACK); \
388
void *__value = (void *) __o1->object_base; \
389
if (__o1->next_free == __value) \
390
__o1->maybe_empty_object = 1; \
392
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
393
__o1->alignment_mask); \
394
if (__o1->next_free - (char *)__o1->chunk \
395
> __o1->chunk_limit - (char *)__o1->chunk) \
396
__o1->next_free = __o1->chunk_limit; \
397
__o1->object_base = __o1->next_free; \
385
# define obstack_finish(OBSTACK) \
387
({ struct obstack *__o1 = (OBSTACK); \
388
void *__value = (void *) __o1->object_base; \
389
if (__o1->next_free == __value) \
390
__o1->maybe_empty_object = 1; \
392
= __PTR_ALIGN (__o1->object_base, __o1->next_free, \
393
__o1->alignment_mask); \
394
if (__o1->next_free - (char *)__o1->chunk \
395
> __o1->chunk_limit - (char *)__o1->chunk) \
396
__o1->next_free = __o1->chunk_limit; \
397
__o1->object_base = __o1->next_free; \
400
# define obstack_free(OBSTACK, OBJ) \
402
({ struct obstack *__o = (OBSTACK); \
403
void *__obj = (OBJ); \
400
# define obstack_free(OBSTACK, OBJ) \
402
({ struct obstack *__o = (OBSTACK); \
403
void *__obj = (OBJ); \
404
404
if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
405
__o->next_free = __o->object_base = (char *)__obj; \
405
__o->next_free = __o->object_base = (char *)__obj; \
406
406
else (__obstack_free) (__o, __obj); })
408
408
#else /* not __GNUC__ or not __STDC__ */
425
425
Casting the third operand to void was tried before,
426
426
but some compilers won't accept it. */
428
# define obstack_make_room(h,length) \
429
( (h)->temp.tempint = (length), \
430
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
428
# define obstack_make_room(h,length) \
429
( (h)->temp.tempint = (length), \
430
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
431
431
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
433
# define obstack_grow(h,where,length) \
434
( (h)->temp.tempint = (length), \
435
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
436
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
437
memcpy ((h)->next_free, where, (h)->temp.tempint), \
433
# define obstack_grow(h,where,length) \
434
( (h)->temp.tempint = (length), \
435
(((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
436
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
437
memcpy ((h)->next_free, where, (h)->temp.tempint), \
438
438
(h)->next_free += (h)->temp.tempint)
440
# define obstack_grow0(h,where,length) \
441
( (h)->temp.tempint = (length), \
442
(((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
443
? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
444
memcpy ((h)->next_free, where, (h)->temp.tempint), \
445
(h)->next_free += (h)->temp.tempint, \
440
# define obstack_grow0(h,where,length) \
441
( (h)->temp.tempint = (length), \
442
(((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
443
? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
444
memcpy ((h)->next_free, where, (h)->temp.tempint), \
445
(h)->next_free += (h)->temp.tempint, \
446
446
*((h)->next_free)++ = 0)
448
# define obstack_1grow(h,datum) \
449
( (((h)->next_free + 1 > (h)->chunk_limit) \
450
? (_obstack_newchunk ((h), 1), 0) : 0), \
448
# define obstack_1grow(h,datum) \
449
( (((h)->next_free + 1 > (h)->chunk_limit) \
450
? (_obstack_newchunk ((h), 1), 0) : 0), \
451
451
obstack_1grow_fast (h, datum))
453
# define obstack_ptr_grow(h,datum) \
454
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
455
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
453
# define obstack_ptr_grow(h,datum) \
454
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
455
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
456
456
obstack_ptr_grow_fast (h, datum))
458
# define obstack_int_grow(h,datum) \
459
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
460
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
458
# define obstack_int_grow(h,datum) \
459
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
460
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
461
461
obstack_int_grow_fast (h, datum))
463
# define obstack_ptr_grow_fast(h,aptr) \
463
# define obstack_ptr_grow_fast(h,aptr) \
464
464
(((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
466
# define obstack_int_grow_fast(h,aint) \
466
# define obstack_int_grow_fast(h,aint) \
467
467
(((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
469
# define obstack_blank(h,length) \
470
( (h)->temp.tempint = (length), \
471
(((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
472
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
469
# define obstack_blank(h,length) \
470
( (h)->temp.tempint = (length), \
471
(((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
472
? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
473
473
obstack_blank_fast (h, (h)->temp.tempint))
475
# define obstack_alloc(h,length) \
475
# define obstack_alloc(h,length) \
476
476
(obstack_blank ((h), (length)), obstack_finish ((h)))
478
# define obstack_copy(h,where,length) \
478
# define obstack_copy(h,where,length) \
479
479
(obstack_grow ((h), (where), (length)), obstack_finish ((h)))
481
# define obstack_copy0(h,where,length) \
481
# define obstack_copy0(h,where,length) \
482
482
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
484
# define obstack_finish(h) \
485
( ((h)->next_free == (h)->object_base \
486
? (((h)->maybe_empty_object = 1), 0) \
488
(h)->temp.tempptr = (h)->object_base, \
490
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
491
(h)->alignment_mask), \
492
(((h)->next_free - (char *) (h)->chunk \
493
> (h)->chunk_limit - (char *) (h)->chunk) \
494
? ((h)->next_free = (h)->chunk_limit) : 0), \
495
(h)->object_base = (h)->next_free, \
484
# define obstack_finish(h) \
485
( ((h)->next_free == (h)->object_base \
486
? (((h)->maybe_empty_object = 1), 0) \
488
(h)->temp.tempptr = (h)->object_base, \
490
= __PTR_ALIGN ((h)->object_base, (h)->next_free, \
491
(h)->alignment_mask), \
492
(((h)->next_free - (char *) (h)->chunk \
493
> (h)->chunk_limit - (char *) (h)->chunk) \
494
? ((h)->next_free = (h)->chunk_limit) : 0), \
495
(h)->object_base = (h)->next_free, \
496
496
(h)->temp.tempptr)
498
# define obstack_free(h,obj) \
499
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
500
((((h)->temp.tempint > 0 \
501
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
502
? (int) ((h)->next_free = (h)->object_base \
503
= (h)->temp.tempint + (char *) (h)->chunk) \
498
# define obstack_free(h,obj) \
499
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
500
((((h)->temp.tempint > 0 \
501
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
502
? (int) ((h)->next_free = (h)->object_base \
503
= (h)->temp.tempint + (char *) (h)->chunk) \
504
504
: (((__obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
506
506
#endif /* not __GNUC__ or not __STDC__ */
508
508
#ifdef __cplusplus
512
512
#endif /* obstack.h */