Subversion Repositories Kolibri OS

Rev

Rev 5191 | Details | Compare with Previous | Last modification | View Log | RSS feed

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