VirtualBox

source: kBuild/vendor/grep/current/lib/obstack.h@ 3530

Last change on this file since 3530 was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette