|
|
1.1 root 1: /* obstack.c - subroutines used implicitly by object stack macros
2: Copyright (C) 1988, 1993 Free Software Foundation, Inc.
3:
4: This program is free software; you can redistribute it and/or modify it
5: under the terms of the GNU General Public License as published by the
6: Free Software Foundation; either version 2, or (at your option) any
7: later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
14: You should have received a copy of the GNU General Public License
15: along with this program; if not, write to the Free Software
16: Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
17:
18: #include "obstack.h"
19:
20: /* This is just to get __GNU_LIBRARY__ defined. */
21: #include <stdio.h>
22:
23: /* Comment out all this code if we are using the GNU C Library, and are not
24: actually compiling the library itself. This code is part of the GNU C
25: Library, but also included in many other GNU distributions. Compiling
26: and linking in this code is a waste when using the GNU C library
27: (especially if it is a shared library). Rather than having every GNU
28: program understand `configure --with-gnu-libc' and omit the object files,
29: it is simpler to just do this in the source for each such file. */
30:
31: #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
32:
33:
34: #ifdef __STDC__
35: #define POINTER void *
36: #else
37: #define POINTER char *
38: #endif
39:
40: /* Determine default alignment. */
41: struct fooalign {char x; double d;};
42: #define DEFAULT_ALIGNMENT \
43: ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
44: /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
45: But in fact it might be less smart and round addresses to as much as
46: DEFAULT_ROUNDING. So we prepare for it to do that. */
47: union fooround {long x; double d;};
48: #define DEFAULT_ROUNDING (sizeof (union fooround))
49:
50: /* When we copy a long block of data, this is the unit to do it with.
51: On some machines, copying successive ints does not work;
52: in such a case, redefine COPYING_UNIT to `long' (if that works)
53: or `char' as a last resort. */
54: #ifndef COPYING_UNIT
55: #define COPYING_UNIT int
56: #endif
57:
58: /* The non-GNU-C macros copy the obstack into this global variable
59: to avoid multiple evaluation. */
60:
61: struct obstack *_obstack;
62:
63: /* Define a macro that either calls functions with the traditional malloc/free
64: calling interface, or calls functions with the mmalloc/mfree interface
65: (that adds an extra first argument), based on the state of use_extra_arg.
66: For free, do not use ?:, since some compilers, like the MIPS compilers,
67: do not allow (expr) ? void : void. */
68:
69: #define CALL_CHUNKFUN(h, size) \
70: (((h) -> use_extra_arg) \
71: ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
72: : (*(h)->chunkfun) ((size)))
73:
74: #define CALL_FREEFUN(h, old_chunk) \
75: do { \
76: if ((h) -> use_extra_arg) \
77: (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
78: else \
79: (*(h)->freefun) ((old_chunk)); \
80: } while (0)
81:
82:
83: /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
84: Objects start on multiples of ALIGNMENT (0 means use default).
85: CHUNKFUN is the function to use to allocate chunks,
86: and FREEFUN the function to free them. */
87:
88: void
89: _obstack_begin (h, size, alignment, chunkfun, freefun)
90: struct obstack *h;
91: int size;
92: int alignment;
93: POINTER (*chunkfun) ();
94: void (*freefun) ();
95: {
96: register struct _obstack_chunk* chunk; /* points to new chunk */
97:
98: if (alignment == 0)
99: alignment = DEFAULT_ALIGNMENT;
100: if (size == 0)
101: /* Default size is what GNU malloc can fit in a 4096-byte block. */
102: {
103: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
104: Use the values for range checking, because if range checking is off,
105: the extra bytes won't be missed terribly, but if range checking is on
106: and we used a larger request, a whole extra 4096 bytes would be
107: allocated.
108:
109: These number are irrelevant to the new GNU malloc. I suspect it is
110: less sensitive to the size of the request. */
111: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
112: + 4 + DEFAULT_ROUNDING - 1)
113: & ~(DEFAULT_ROUNDING - 1));
114: size = 4096 - extra;
115: }
116:
117: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
118: h->freefun = freefun;
119: h->chunk_size = size;
120: h->alignment_mask = alignment - 1;
121: h->use_extra_arg = 0;
122:
123: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
124: h->next_free = h->object_base = chunk->contents;
125: h->chunk_limit = chunk->limit
126: = (char *) chunk + h->chunk_size;
127: chunk->prev = 0;
128: /* The initial chunk now contains no empty object. */
129: h->maybe_empty_object = 0;
130: }
131:
132: void
133: _obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
134: struct obstack *h;
135: int size;
136: int alignment;
137: POINTER (*chunkfun) ();
138: void (*freefun) ();
139: POINTER arg;
140: {
141: register struct _obstack_chunk* chunk; /* points to new chunk */
142:
143: if (alignment == 0)
144: alignment = DEFAULT_ALIGNMENT;
145: if (size == 0)
146: /* Default size is what GNU malloc can fit in a 4096-byte block. */
147: {
148: /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
149: Use the values for range checking, because if range checking is off,
150: the extra bytes won't be missed terribly, but if range checking is on
151: and we used a larger request, a whole extra 4096 bytes would be
152: allocated.
153:
154: These number are irrelevant to the new GNU malloc. I suspect it is
155: less sensitive to the size of the request. */
156: int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
157: + 4 + DEFAULT_ROUNDING - 1)
158: & ~(DEFAULT_ROUNDING - 1));
159: size = 4096 - extra;
160: }
161:
162: h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
163: h->freefun = freefun;
164: h->chunk_size = size;
165: h->alignment_mask = alignment - 1;
166: h->extra_arg = arg;
167: h->use_extra_arg = 1;
168:
169: chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
170: h->next_free = h->object_base = chunk->contents;
171: h->chunk_limit = chunk->limit
172: = (char *) chunk + h->chunk_size;
173: chunk->prev = 0;
174: /* The initial chunk now contains no empty object. */
175: h->maybe_empty_object = 0;
176: }
177:
178: /* Allocate a new current chunk for the obstack *H
179: on the assumption that LENGTH bytes need to be added
180: to the current object, or a new object of length LENGTH allocated.
181: Copies any partial object from the end of the old chunk
182: to the beginning of the new one. */
183:
184: void
185: _obstack_newchunk (h, length)
186: struct obstack *h;
187: int length;
188: {
189: register struct _obstack_chunk* old_chunk = h->chunk;
190: register struct _obstack_chunk* new_chunk;
191: register long new_size;
192: register int obj_size = h->next_free - h->object_base;
193: register int i;
194: int already;
195:
196: /* Compute size for new chunk. */
197: new_size = (obj_size + length) + (obj_size >> 3) + 100;
198: if (new_size < h->chunk_size)
199: new_size = h->chunk_size;
200:
201: /* Allocate and initialize the new chunk. */
202: new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
203: new_chunk->prev = old_chunk;
204: new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
205:
206: /* Move the existing object to the new chunk.
207: Word at a time is fast and is safe if the object
208: is sufficiently aligned. */
209: if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
210: {
211: for (i = obj_size / sizeof (COPYING_UNIT) - 1;
212: i >= 0; i--)
213: ((COPYING_UNIT *)new_chunk->contents)[i]
214: = ((COPYING_UNIT *)h->object_base)[i];
215: /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
216: but that can cross a page boundary on a machine
217: which does not do strict alignment for COPYING_UNITS. */
218: already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
219: }
220: else
221: already = 0;
222: /* Copy remaining bytes one by one. */
223: for (i = already; i < obj_size; i++)
224: new_chunk->contents[i] = h->object_base[i];
225:
226: /* If the object just copied was the only data in OLD_CHUNK,
227: free that chunk and remove it from the chain.
228: But not if that chunk might contain an empty object. */
229: if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
230: {
231: new_chunk->prev = old_chunk->prev;
232: CALL_FREEFUN (h, old_chunk);
233: }
234:
235: h->object_base = new_chunk->contents;
236: h->next_free = h->object_base + obj_size;
237: /* The new chunk certainly contains no empty object yet. */
238: h->maybe_empty_object = 0;
239: }
240:
241: /* Return nonzero if object OBJ has been allocated from obstack H.
242: This is here for debugging.
243: If you use it in a program, you are probably losing. */
244:
245: #ifdef __STDC__
246: /* Suppress -Wmissing-prototypes warning. We don't want to declare this in
247: obstack.h because it is just for debugging. */
248: int _obstack_allocated_p (struct obstack *h, POINTER obj);
249: #endif
250:
251: int
252: _obstack_allocated_p (h, obj)
253: struct obstack *h;
254: POINTER obj;
255: {
256: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
257: register struct _obstack_chunk* plp; /* point to previous chunk if any */
258:
259: lp = (h)->chunk;
260: /* We use >= rather than > since the object cannot be exactly at
261: the beginning of the chunk but might be an empty object exactly
262: at the end of an adjacent chunk. */
263: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
264: {
265: plp = lp->prev;
266: lp = plp;
267: }
268: return lp != 0;
269: }
270:
271: /* Free objects in obstack H, including OBJ and everything allocate
272: more recently than OBJ. If OBJ is zero, free everything in H. */
273:
274: #undef obstack_free
275:
276: /* This function has two names with identical definitions.
277: This is the first one, called from non-ANSI code. */
278:
279: void
280: _obstack_free (h, obj)
281: struct obstack *h;
282: POINTER obj;
283: {
284: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
285: register struct _obstack_chunk* plp; /* point to previous chunk if any */
286:
287: lp = h->chunk;
288: /* We use >= because there cannot be an object at the beginning of a chunk.
289: But there can be an empty object at that address
290: at the end of another chunk. */
291: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
292: {
293: plp = lp->prev;
294: CALL_FREEFUN (h, lp);
295: lp = plp;
296: /* If we switch chunks, we can't tell whether the new current
297: chunk contains an empty object, so assume that it may. */
298: h->maybe_empty_object = 1;
299: }
300: if (lp)
301: {
302: h->object_base = h->next_free = (char *)(obj);
303: h->chunk_limit = lp->limit;
304: h->chunk = lp;
305: }
306: else if (obj != 0)
307: /* obj is not in any of the chunks! */
308: abort ();
309: }
310:
311: /* This function is used from ANSI code. */
312:
313: void
314: obstack_free (h, obj)
315: struct obstack *h;
316: POINTER obj;
317: {
318: register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
319: register struct _obstack_chunk* plp; /* point to previous chunk if any */
320:
321: lp = h->chunk;
322: /* We use >= because there cannot be an object at the beginning of a chunk.
323: But there can be an empty object at that address
324: at the end of another chunk. */
325: while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
326: {
327: plp = lp->prev;
328: CALL_FREEFUN (h, lp);
329: lp = plp;
330: /* If we switch chunks, we can't tell whether the new current
331: chunk contains an empty object, so assume that it may. */
332: h->maybe_empty_object = 1;
333: }
334: if (lp)
335: {
336: h->object_base = h->next_free = (char *)(obj);
337: h->chunk_limit = lp->limit;
338: h->chunk = lp;
339: }
340: else if (obj != 0)
341: /* obj is not in any of the chunks! */
342: abort ();
343: }
344:
345:
346: /* Return the size of all the objects in OBSTACK. This is only an
347: approximation, since we can't know how much space of previous
348: chunks was wasted at the top.... */
349:
350: int
351: obstack_size (obstack)
352: struct obstack *obstack;
353: {
354: struct _obstack_chunk *chunk;
355: unsigned int chunk_count = 0;
356:
357: for (chunk = obstack->chunk; chunk != 0; chunk = chunk->prev)
358: chunk_count++;
359:
360: return obstack->next_free - obstack->chunk->contents
361: + (chunk_count - 1) * (obstack->chunk_limit - obstack->chunk->contents);
362: }
363:
364: #if 0
365: /* These are now turned off because the applications do not use it
366: and it uses bcopy via obstack_grow, which causes trouble on sysV. */
367:
368: /* Now define the functional versions of the obstack macros.
369: Define them to simply use the corresponding macros to do the job. */
370:
371: #ifdef __STDC__
372: /* These function definitions do not work with non-ANSI preprocessors;
373: they won't pass through the macro names in parentheses. */
374:
375: /* The function names appear in parentheses in order to prevent
376: the macro-definitions of the names from being expanded there. */
377:
378: POINTER (obstack_base) (obstack)
379: struct obstack *obstack;
380: {
381: return obstack_base (obstack);
382: }
383:
384: POINTER (obstack_next_free) (obstack)
385: struct obstack *obstack;
386: {
387: return obstack_next_free (obstack);
388: }
389:
390: int (obstack_object_size) (obstack)
391: struct obstack *obstack;
392: {
393: return obstack_object_size (obstack);
394: }
395:
396: int (obstack_room) (obstack)
397: struct obstack *obstack;
398: {
399: return obstack_room (obstack);
400: }
401:
402: void (obstack_grow) (obstack, pointer, length)
403: struct obstack *obstack;
404: POINTER pointer;
405: int length;
406: {
407: obstack_grow (obstack, pointer, length);
408: }
409:
410: void (obstack_grow0) (obstack, pointer, length)
411: struct obstack *obstack;
412: POINTER pointer;
413: int length;
414: {
415: obstack_grow0 (obstack, pointer, length);
416: }
417:
418: void (obstack_1grow) (obstack, character)
419: struct obstack *obstack;
420: int character;
421: {
422: obstack_1grow (obstack, character);
423: }
424:
425: void (obstack_blank) (obstack, length)
426: struct obstack *obstack;
427: int length;
428: {
429: obstack_blank (obstack, length);
430: }
431:
432: void (obstack_1grow_fast) (obstack, character)
433: struct obstack *obstack;
434: int character;
435: {
436: obstack_1grow_fast (obstack, character);
437: }
438:
439: void (obstack_blank_fast) (obstack, length)
440: struct obstack *obstack;
441: int length;
442: {
443: obstack_blank_fast (obstack, length);
444: }
445:
446: POINTER (obstack_finish) (obstack)
447: struct obstack *obstack;
448: {
449: return obstack_finish (obstack);
450: }
451:
452: POINTER (obstack_alloc) (obstack, length)
453: struct obstack *obstack;
454: int length;
455: {
456: return obstack_alloc (obstack, length);
457: }
458:
459: POINTER (obstack_copy) (obstack, pointer, length)
460: struct obstack *obstack;
461: POINTER pointer;
462: int length;
463: {
464: return obstack_copy (obstack, pointer, length);
465: }
466:
467: POINTER (obstack_copy0) (obstack, pointer, length)
468: struct obstack *obstack;
469: POINTER pointer;
470: int length;
471: {
472: return obstack_copy0 (obstack, pointer, length);
473: }
474:
475: #endif /* __STDC__ */
476:
477: #endif /* 0 */
478:
479: #endif /* _LIBC or not __GNU_LIBRARY__. */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.