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
~Obstack()93 inline Obstack::~Obstack()
94 {
95 _free(0);
96 }
97
base()98 inline void* Obstack::base()
99 {
100 return objectbase;
101 }
102
next_free()103 inline void* Obstack::next_free()
104 {
105 return nextfree;
106 }
107
alignment_mask()108 inline int Obstack::alignment_mask()
109 {
110 return alignmentmask;
111 }
112
chunk_size()113 inline int Obstack::chunk_size()
114 {
115 return chunksize;
116 }
117
size()118 inline int Obstack::size()
119 {
120 return nextfree - objectbase;
121 }
122
room()123 inline int Obstack::room()
124 {
125 return chunklimit - nextfree;
126 }
127
grow(const void * data,int size)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
grow(const void * data,int size,char terminator)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
grow(const char * s)145 inline void Obstack:: grow(const char* s)
146 {
147 grow((void*)s, strlen(s), 0);
148 }
149
grow(char c)150 inline void Obstack:: grow(char c)
151 {
152 if (nextfree+1 > chunklimit)
153 newchunk(1);
154 *(nextfree)++ = c;
155 }
156
blank(int size)157 inline void Obstack:: blank(int size)
158 {
159 if (nextfree+size > chunklimit)
160 newchunk(size);
161 nextfree += size;
162 }
163
finish(char terminator)164 inline void* Obstack::finish(char terminator)
165 {
166 grow(terminator);
167 return finish();
168 }
169
copy(const void * data,int size)170 inline void* Obstack::copy(const void* data, int size)
171 {
172 grow (data, size);
173 return finish();
174 }
175
copy(const void * data,int size,char terminator)176 inline void* Obstack::copy(const void* data, int size, char terminator)
177 {
178 grow(data, size, terminator);
179 return finish();
180 }
181
copy(const char * s)182 inline void* Obstack::copy(const char* s)
183 {
184 grow((void*)s, strlen(s), 0);
185 return finish();
186 }
187
copy(char c)188 inline void* Obstack::copy(char c)
189 {
190 grow(c);
191 return finish();
192 }
193
alloc(int size)194 inline void* Obstack::alloc(int size)
195 {
196 blank(size);
197 return finish();
198 }
199
free(void * obj)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
grow_fast(char c)208 inline void Obstack:: grow_fast(char c)
209 {
210 *(nextfree)++ = c;
211 }
212
blank_fast(int size)213 inline void Obstack:: blank_fast(int size)
214 {
215 nextfree += size;
216 }
217
shrink(int size)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
227