Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | // This may look like C code, but it is really -*- C++ -*- |
2 | /* | |
3 | Copyright (C) 1988 Free Software Foundation | |
4 | written by Doug Lea (dl@rocky.oswego.edu) | |
5 | ||
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC is distributed in the hope that it will be useful, | |
9 | but WITHOUT ANY WARRANTY. No author or distributor | |
10 | accepts responsibility to anyone for the consequences of using it | |
11 | or for whether it serves any particular purpose or works at all, | |
12 | unless he says so in writing. Refer to the GNU CC General Public | |
13 | License for full details. | |
14 | ||
15 | Everyone is granted permission to copy, modify and redistribute | |
16 | GNU CC, but only under the conditions described in the | |
17 | GNU CC General Public License. A copy of this license is | |
18 | supposed to have been given to you along with GNU CC so you | |
19 | can know your rights and responsibilities. It should be in a | |
20 | file named COPYING. Among other things, the copyright notice | |
21 | and this notice must be preserved on all copies. | |
22 | */ | |
23 | ||
24 | ||
25 | #ifndef _Obstack_h | |
26 | #ifdef __GNUG__ | |
27 | #pragma once | |
28 | #pragma interface | |
29 | #endif | |
30 | #define _Obstack_h 1 | |
31 | ||
32 | #include <std.h> | |
33 | ||
34 | class Obstack | |
35 | { | |
36 | struct _obstack_chunk | |
37 | { | |
38 | char* limit; | |
39 | _obstack_chunk* prev; | |
40 | char contents[4]; | |
41 | }; | |
42 | ||
43 | protected: | |
44 | long chunksize; | |
45 | _obstack_chunk* chunk; | |
46 | char* objectbase; | |
47 | char* nextfree; | |
48 | char* chunklimit; | |
49 | int alignmentmask; | |
50 | ||
51 | void _free(void* obj); | |
52 | void newchunk(int size); | |
53 | ||
54 | public: | |
55 | Obstack(int size = 4080, int alignment = 4); // 4080=4096-mallocslop | |
56 | ||
57 | ~Obstack(); | |
58 | ||
59 | void* base(); | |
60 | void* next_free(); | |
61 | int alignment_mask(); | |
62 | int chunk_size(); | |
63 | int size(); | |
64 | int room(); | |
65 | int contains(void* p); // does Obstack hold pointer p? | |
66 | ||
67 | void grow(const void* data, int size); | |
68 | void grow(const void* data, int size, char terminator); | |
69 | void grow(const char* s); | |
70 | void grow(char c); | |
71 | void grow_fast(char c); | |
72 | void blank(int size); | |
73 | void blank_fast(int size); | |
74 | ||
75 | void* finish(); | |
76 | void* finish(char terminator); | |
77 | ||
78 | void* copy(const void* data, int size); | |
79 | void* copy(const void* data, int size, char terminator); | |
80 | void* copy(const char* s); | |
81 | void* copy(char c); | |
82 | void* alloc(int size); | |
83 | ||
84 | void free(void* obj); | |
85 | void shrink(int size = 1); // suggested by ken@cs.rochester.edu | |
86 | ||
87 | int OK(); // rep invariant | |
88 | }; | |
89 | ||
90 | #if defined(__OPTIMIZE__) || defined(USE_LIBGXX_INLINES) | |
91 | ||
92 | ||
93 | inline Obstack::~Obstack() | |
94 | { | |
95 | _free(0); | |
96 | } | |
97 | ||
98 | inline void* Obstack::base() | |
99 | { | |
100 | return objectbase; | |
101 | } | |
102 | ||
103 | inline void* Obstack::next_free() | |
104 | { | |
105 | return nextfree; | |
106 | } | |
107 | ||
108 | inline int Obstack::alignment_mask() | |
109 | { | |
110 | return alignmentmask; | |
111 | } | |
112 | ||
113 | inline int Obstack::chunk_size() | |
114 | { | |
115 | return chunksize; | |
116 | } | |
117 | ||
118 | inline int Obstack::size() | |
119 | { | |
120 | return nextfree - objectbase; | |
121 | } | |
122 | ||
123 | inline int Obstack::room() | |
124 | { | |
125 | return chunklimit - nextfree; | |
126 | } | |
127 | ||
128 | inline void Obstack:: grow(const void* data, int size) | |
129 | { | |
130 | if (nextfree+size > chunklimit) | |
131 | newchunk(size); | |
132 | bcopy(data, nextfree, size); | |
133 | nextfree += size; | |
134 | } | |
135 | ||
136 | inline void Obstack:: grow(const void* data, int size, char terminator) | |
137 | { | |
138 | if (nextfree+size+1 > chunklimit) | |
139 | newchunk(size+1); | |
140 | bcopy(data, nextfree, size); | |
141 | nextfree += size; | |
142 | *(nextfree)++ = terminator; | |
143 | } | |
144 | ||
145 | inline void Obstack:: grow(const char* s) | |
146 | { | |
147 | grow((void*)s, strlen(s), 0); | |
148 | } | |
149 | ||
150 | inline void Obstack:: grow(char c) | |
151 | { | |
152 | if (nextfree+1 > chunklimit) | |
153 | newchunk(1); | |
154 | *(nextfree)++ = c; | |
155 | } | |
156 | ||
157 | inline void Obstack:: blank(int size) | |
158 | { | |
159 | if (nextfree+size > chunklimit) | |
160 | newchunk(size); | |
161 | nextfree += size; | |
162 | } | |
163 | ||
164 | inline void* Obstack::finish(char terminator) | |
165 | { | |
166 | grow(terminator); | |
167 | return finish(); | |
168 | } | |
169 | ||
170 | inline void* Obstack::copy(const void* data, int size) | |
171 | { | |
172 | grow (data, size); | |
173 | return finish(); | |
174 | } | |
175 | ||
176 | inline void* Obstack::copy(const void* data, int size, char terminator) | |
177 | { | |
178 | grow(data, size, terminator); | |
179 | return finish(); | |
180 | } | |
181 | ||
182 | inline void* Obstack::copy(const char* s) | |
183 | { | |
184 | grow((void*)s, strlen(s), 0); | |
185 | return finish(); | |
186 | } | |
187 | ||
188 | inline void* Obstack::copy(char c) | |
189 | { | |
190 | grow(c); | |
191 | return finish(); | |
192 | } | |
193 | ||
194 | inline void* Obstack::alloc(int size) | |
195 | { | |
196 | blank(size); | |
197 | return finish(); | |
198 | } | |
199 | ||
200 | inline void Obstack:: free(void* obj) | |
201 | { | |
202 | if (obj >= (void*)chunk && obj<(void*)chunklimit) | |
203 | nextfree = objectbase = (char *) obj; | |
204 | else | |
205 | _free(obj); | |
206 | } | |
207 | ||
208 | inline void Obstack:: grow_fast(char c) | |
209 | { | |
210 | *(nextfree)++ = c; | |
211 | } | |
212 | ||
213 | inline void Obstack:: blank_fast(int size) | |
214 | { | |
215 | nextfree += size; | |
216 | } | |
217 | ||
218 | inline void Obstack:: shrink(int size) // from ken@cs.rochester.edu | |
219 | { | |
220 | if (nextfree >= objectbase + size) | |
221 | nextfree -= size; | |
222 | } | |
223 | ||
224 | #endif | |
225 | ||
226 | #endif |