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