source: branches/libc-0.6/src/emx/include/obstack.h@ 3682

Last change on this file since 3682 was 2155, checked in by bird, 20 years ago

Added obstack.h and it's implementation from GLIBC.

  • Property cvs2svn:cvs-rev set to 1.3
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 18.6 KB
Line 
1/* obstack.h - object stack macros
2 Copyright (C) 1988-1994,1996-1999,2003,2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. Its master source is NOT part of
4 the C library, however. The master source lives in /gd/gnu/lib.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20/** @file
21 * GLIBC 2.3.x CVS
22 */
23
24/* Summary:
25
26All the apparent functions defined here are macros. The idea
27is that you would use these pre-tested macros to solve a
28very specific set of problems, and they would run fast.
29Caution: no side-effects in arguments please!! They may be
30evaluated MANY times!!
31
32These macros operate a stack of objects. Each object starts life
33small, and may grow to maturity. (Consider building a word syllable
34by syllable.) An object can move while it is growing. Once it has
35been "finished" it never changes address again. So the "top of the
36stack" is typically an immature growing object, while the rest of the
37stack is of mature, fixed size and fixed address objects.
38
39These routines grab large chunks of memory, using a function you
40supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
41by calling `obstack_chunk_free'. You must define them and declare
42them before using any obstack macros.
43
44Each independent stack is represented by a `struct obstack'.
45Each of the obstack macros expects a pointer to such a structure
46as the first argument.
47
48One motivation for this package is the problem of growing char strings
49in symbol tables. Unless you are "fascist pig with a read-only mind"
50--Gosper's immortal quote from HAKMEM item 154, out of context--you
51would not like to put any arbitrary upper limit on the length of your
52symbols.
53
54In practice this often means you will build many short symbols and a
55few long symbols. At the time you are reading a symbol you don't know
56how long it is. One traditional method is to read a symbol into a
57buffer, realloc()ating the buffer every time you try to read a symbol
58that is longer than the buffer. This is beaut, but you still will
59want to copy the symbol from the buffer to a more permanent
60symbol-table entry say about half the time.
61
62With obstacks, you can work differently. Use one obstack for all symbol
63names. As you read a symbol, grow the name in the obstack gradually.
64When the name is complete, finalize it. Then, if the symbol exists already,
65free the newly read name.
66
67The way we do this is to take a large chunk, allocating memory from
68low addresses. When you want to build a symbol in the chunk you just
69add chars above the current "high water mark" in the chunk. When you
70have finished adding chars, because you got to the end of the symbol,
71you know how long the chars are, and you can create a new object.
72Mostly the chars will not burst over the highest address of the chunk,
73because you would typically expect a chunk to be (say) 100 times as
74long as an average object.
75
76In case that isn't clear, when we have enough chars to make up
77the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
78so we just point to it where it lies. No moving of chars is
79needed and this is the second win: potentially long strings need
80never be explicitly shuffled. Once an object is formed, it does not
81change its address during its lifetime.
82
83When the chars burst over a chunk boundary, we allocate a larger
84chunk, and then copy the partly formed object from the end of the old
85chunk to the beginning of the new larger chunk. We then carry on
86accreting characters to the end of the object as we normally would.
87
88A special macro is provided to add a single char at a time to a
89growing object. This allows the use of register variables, which
90break the ordinary 'growth' macro.
91
92Summary:
93 We allocate large chunks.
94 We carve out one object at a time from the current chunk.
95 Once carved, an object never moves.
96 We are free to append data of any size to the currently
97 growing object.
98 Exactly one object is growing in an obstack at any one time.
99 You can run one obstack per control block.
100 You may have as many control blocks as you dare.
101 Because of the way we do it, you can `unwind' an obstack
102 back to a previous state. (You may remove objects much
103 as you would with a stack.)
104*/
105
106
107/* Don't do the contents of this file more than once. */
108
109#ifndef _OBSTACK_H
110#define _OBSTACK_H 1
111
112#ifdef __cplusplus
113extern "C" {
114#endif
115
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, include <stddef.h>
132 and use ptrdiff_t. */
133
134#ifdef __PTRDIFF_TYPE__
135# define PTR_INT_TYPE __PTRDIFF_TYPE__
136#else
137# include <stddef.h>
138# define PTR_INT_TYPE ptrdiff_t
139#endif
140
141#include <string.h>
142
143struct _obstack_chunk /* Lives at front of each chunk. */
144{
145 char *limit; /* 1 past end of this chunk */
146 struct _obstack_chunk *prev; /* address of prior chunk or NULL */
147 char contents[4]; /* objects begin here */
148};
149
150struct obstack /* control current object in current chunk */
151{
152 long chunk_size; /* preferred size to allocate chunks in */
153 struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
154 char *object_base; /* address of object we are building */
155 char *next_free; /* where to add next char to current object */
156 char *chunk_limit; /* address of char after current chunk */
157 PTR_INT_TYPE temp; /* Temporary for some macros. */
158 int alignment_mask; /* Mask of alignment for each object. */
159 /* These prototypes vary based on `use_extra_arg', and we use
160 casts to the prototypeless function type in all assignments,
161 but having prototypes here quiets -Wstrict-prototypes. */
162 struct _obstack_chunk *(*chunkfun) (void *, long);
163 void (*freefun) (void *, struct _obstack_chunk *);
164 void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
165 unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
166 unsigned maybe_empty_object:1;/* There is a possibility that the current
167 chunk contains a zero-length object. This
168 prevents freeing the chunk if we allocate
169 a bigger chunk to replace it. */
170 unsigned alloc_failed:1; /* No longer used, as we now call the failed
171 handler on error, but retained for binary
172 compatibility. */
173};
174
175/* Declare the external functions we use; they are in obstack.c. */
176
177extern void _obstack_newchunk (struct obstack *, int);
178extern int _obstack_begin (struct obstack *, int, int,
179 void *(*) (long), void (*) (void *));
180extern int _obstack_begin_1 (struct obstack *, int, int,
181 void *(*) (void *, long),
182 void (*) (void *, void *), void *);
183extern int _obstack_memory_used (struct obstack *);
184
185void obstack_free (struct obstack *obstack, void *block);
186
187
188
189/* Error handler called when `obstack_chunk_alloc' failed to allocate
190 more memory. This can be set to a user defined function which
191 should either abort gracefully or use longjump - but shouldn't
192 return. The default action is to print a message and abort. */
193extern void (*obstack_alloc_failed_handler) (void);
194
195/* Exit value used when `print_and_abort' is used. */
196extern int obstack_exit_failure;
197
198
199/* Pointer to beginning of object being allocated or to be allocated next.
200 Note that this might not be the final address of the object
201 because a new chunk might be needed to hold the final size. */
202
203#define obstack_base(h) ((void *) (h)->object_base)
204
205/* Size for allocating ordinary chunks. */
206
207#define obstack_chunk_size(h) ((h)->chunk_size)
208
209/* Pointer to next byte not yet allocated in current chunk. */
210
211#define obstack_next_free(h) ((h)->next_free)
212
213/* Mask specifying low bits that should be clear in address of an object. */
214
215#define obstack_alignment_mask(h) ((h)->alignment_mask)
216
217/* To prevent prototype warnings provide complete argument list. */
218#define obstack_init(h) \
219 _obstack_begin ((h), 0, 0, \
220 (void *(*) (long)) obstack_chunk_alloc, \
221 (void (*) (void *)) obstack_chunk_free)
222
223#define obstack_begin(h, size) \
224 _obstack_begin ((h), (size), 0, \
225 (void *(*) (long)) obstack_chunk_alloc, \
226 (void (*) (void *)) obstack_chunk_free)
227
228#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
229 _obstack_begin ((h), (size), (alignment), \
230 (void *(*) (long)) (chunkfun), \
231 (void (*) (void *)) (freefun))
232
233#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
234 _obstack_begin_1 ((h), (size), (alignment), \
235 (void *(*) (void *, long)) (chunkfun), \
236 (void (*) (void *, void *)) (freefun), (arg))
237
238#define obstack_chunkfun(h, newchunkfun) \
239 ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
240
241#define obstack_freefun(h, newfreefun) \
242 ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
243
244#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
245
246#define obstack_blank_fast(h,n) ((h)->next_free += (n))
247
248#define obstack_memory_used(h) _obstack_memory_used (h)
249
250
251#if defined __GNUC__ && defined __STDC__ && __STDC__
252/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
253 does not implement __extension__. But that compiler doesn't define
254 __GNUC_MINOR__. */
255# if __GNUC__ < 2 || (defined __NeXT__ && __NeXT__ && !__GNUC_MINOR__)
256# define __extension__
257# endif
258
259/* For GNU C, if not -traditional,
260 we can define these macros to compute all args only once
261 without using a global variable.
262 Also, we can avoid using the `temp' slot, to make faster code. */
263
264# define obstack_object_size(OBSTACK) \
265 __extension__ \
266 ({ struct obstack const *__o = (OBSTACK); \
267 (unsigned) (__o->next_free - __o->object_base); })
268
269# define obstack_room(OBSTACK) \
270 __extension__ \
271 ({ struct obstack const *__o = (OBSTACK); \
272 (unsigned) (__o->chunk_limit - __o->next_free); })
273
274# define obstack_make_room(OBSTACK,length) \
275__extension__ \