1169695Skan/* obstack.c - subroutines used implicitly by object stack macros
2169695Skan   Copyright (C) 1988,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
3169695Skan
4169695Skan
5169695Skan   NOTE: This source is derived from an old version taken from the GNU C
6169695Skan   Library (glibc).
7169695Skan
8169695Skan   This program is free software; you can redistribute it and/or modify it
9169695Skan   under the terms of the GNU General Public License as published by the
10169695Skan   Free Software Foundation; either version 2, or (at your option) any
11169695Skan   later version.
12169695Skan
13169695Skan   This program is distributed in the hope that it will be useful,
14169695Skan   but WITHOUT ANY WARRANTY; without even the implied warranty of
15169695Skan   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16169695Skan   GNU General Public License for more details.
17169695Skan
18169695Skan   You should have received a copy of the GNU General Public License
19169695Skan   along with this program; if not, write to the Free Software
20169695Skan   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
21169695Skan   USA.  */
22169695Skan
23169695Skan#ifdef HAVE_CONFIG_H
24169695Skan#include <config.h>
25169695Skan#endif
26169695Skan
27169695Skan#include "obstack.h"
28169695Skan
29169695Skan/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
30169695Skan   incremented whenever callers compiled using an old obstack.h can no
31169695Skan   longer properly call the functions in this obstack.c.  */
32169695Skan#define OBSTACK_INTERFACE_VERSION 1
33169695Skan
34169695Skan/* Comment out all this code if we are using the GNU C Library, and are not
35169695Skan   actually compiling the library itself, and the installed library
36169695Skan   supports the same library interface we do.  This code is part of the GNU
37169695Skan   C Library, but also included in many other GNU distributions.  Compiling
38169695Skan   and linking in this code is a waste when using the GNU C library
39169695Skan   (especially if it is a shared library).  Rather than having every GNU
40169695Skan   program understand `configure --with-gnu-libc' and omit the object
41169695Skan   files, it is simpler to just do this in the source for each such file.  */
42169695Skan
43169695Skan#include <stdio.h>		/* Random thing to get __GNU_LIBRARY__.  */
44169695Skan#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
45169695Skan#include <gnu-versions.h>
46169695Skan#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
47169695Skan#define ELIDE_CODE
48169695Skan#endif
49169695Skan#endif
50169695Skan
51169695Skan
52169695Skan#ifndef ELIDE_CODE
53169695Skan
54169695Skan
55169695Skan#define POINTER void *
56169695Skan
57169695Skan/* Determine default alignment.  */
58169695Skanstruct fooalign {char x; double d;};
59169695Skan#define DEFAULT_ALIGNMENT  \
60169695Skan  ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
61169695Skan/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
62169695Skan   But in fact it might be less smart and round addresses to as much as
63169695Skan   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
64169695Skanunion fooround {long x; double d;};
65169695Skan#define DEFAULT_ROUNDING (sizeof (union fooround))
66169695Skan
67169695Skan/* When we copy a long block of data, this is the unit to do it with.
68169695Skan   On some machines, copying successive ints does not work;
69169695Skan   in such a case, redefine COPYING_UNIT to `long' (if that works)
70169695Skan   or `char' as a last resort.  */
71169695Skan#ifndef COPYING_UNIT
72169695Skan#define COPYING_UNIT int
73169695Skan#endif
74169695Skan
75169695Skan
76169695Skan/* The functions allocating more room by calling `obstack_chunk_alloc'
77169695Skan   jump to the handler pointed to by `obstack_alloc_failed_handler'.
78169695Skan   This variable by default points to the internal function
79169695Skan   `print_and_abort'.  */
80169695Skanstatic void print_and_abort (void);
81169695Skanvoid (*obstack_alloc_failed_handler) (void) = print_and_abort;
82169695Skan
83169695Skan/* Exit value used when `print_and_abort' is used.  */
84169695Skan#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
85169695Skan#include <stdlib.h>
86169695Skan#endif
87169695Skan#ifndef EXIT_FAILURE
88169695Skan#define EXIT_FAILURE 1
89169695Skan#endif
90169695Skanint obstack_exit_failure = EXIT_FAILURE;
91169695Skan
92169695Skan/* The non-GNU-C macros copy the obstack into this global variable
93169695Skan   to avoid multiple evaluation.  */
94169695Skan
95169695Skanstruct obstack *_obstack;
96169695Skan
97169695Skan/* Define a macro that either calls functions with the traditional malloc/free
98169695Skan   calling interface, or calls functions with the mmalloc/mfree interface
99169695Skan   (that adds an extra first argument), based on the state of use_extra_arg.
100169695Skan   For free, do not use ?:, since some compilers, like the MIPS compilers,
101169695Skan   do not allow (expr) ? void : void.  */
102169695Skan
103169695Skan#if defined (__STDC__) && __STDC__
104169695Skan#define CALL_CHUNKFUN(h, size) \
105169695Skan  (((h) -> use_extra_arg) \
106169695Skan   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
107169695Skan   : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
108169695Skan
109169695Skan#define CALL_FREEFUN(h, old_chunk) \
110169695Skan  do { \
111169695Skan    if ((h) -> use_extra_arg) \
112169695Skan      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
113169695Skan    else \
114169695Skan      (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
115169695Skan  } while (0)
116169695Skan#else
117169695Skan#define CALL_CHUNKFUN(h, size) \
118169695Skan  (((h) -> use_extra_arg) \
119169695Skan   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
120169695Skan   : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
121169695Skan
122169695Skan#define CALL_FREEFUN(h, old_chunk) \
123169695Skan  do { \
124169695Skan    if ((h) -> use_extra_arg) \
125169695Skan      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
126169695Skan    else \
127169695Skan      (*(void (*) ()) (h)->freefun) ((old_chunk)); \
128169695Skan  } while (0)
129169695Skan#endif
130169695Skan
131169695Skan
132169695Skan/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
133169695Skan   Objects start on multiples of ALIGNMENT (0 means use default).
134169695Skan   CHUNKFUN is the function to use to allocate chunks,
135169695Skan   and FREEFUN the function to free them.
136169695Skan
137169695Skan   Return nonzero if successful, zero if out of memory.
138169695Skan   To recover from an out of memory error,
139169695Skan   free up some memory, then call this again.  */
140169695Skan
141169695Skanint
142169695Skan_obstack_begin (struct obstack *h, int size, int alignment,
143169695Skan                POINTER (*chunkfun) (long), void (*freefun) (void *))
144169695Skan{
145169695Skan  register struct _obstack_chunk *chunk; /* points to new chunk */
146169695Skan
147169695Skan  if (alignment == 0)
148169695Skan    alignment = (int) DEFAULT_ALIGNMENT;
149169695Skan  if (size == 0)
150169695Skan    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
151169695Skan    {
152169695Skan      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
153169695Skan	 Use the values for range checking, because if range checking is off,
154169695Skan	 the extra bytes won't be missed terribly, but if range checking is on
155169695Skan	 and we used a larger request, a whole extra 4096 bytes would be
156169695Skan	 allocated.
157169695Skan
158169695Skan	 These number are irrelevant to the new GNU malloc.  I suspect it is
159169695Skan	 less sensitive to the size of the request.  */
160169695Skan      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
161169695Skan		    + 4 + DEFAULT_ROUNDING - 1)
162169695Skan		   & ~(DEFAULT_ROUNDING - 1));
163169695Skan      size = 4096 - extra;
164169695Skan    }
165169695Skan
166169695Skan  h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
167169695Skan  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
168169695Skan  h->chunk_size = size;
169169695Skan  h->alignment_mask = alignment - 1;
170169695Skan  h->use_extra_arg = 0;
171169695Skan
172169695Skan  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
173169695Skan  if (!chunk)
174169695Skan    (*obstack_alloc_failed_handler) ();
175169695Skan  h->next_free = h->object_base = chunk->contents;
176169695Skan  h->chunk_limit = chunk->limit
177169695Skan    = (char *) chunk + h->chunk_size;
178169695Skan  chunk->prev = 0;
179169695Skan  /* The initial chunk now contains no empty object.  */
180169695Skan  h->maybe_empty_object = 0;
181169695Skan  h->alloc_failed = 0;
182169695Skan  return 1;
183169695Skan}
184169695Skan
185169695Skanint
186169695Skan_obstack_begin_1 (struct obstack *h, int size, int alignment,
187169695Skan                  POINTER (*chunkfun) (POINTER, long),
188169695Skan                  void (*freefun) (POINTER, POINTER), POINTER arg)
189169695Skan{
190169695Skan  register struct _obstack_chunk *chunk; /* points to new chunk */
191169695Skan
192169695Skan  if (alignment == 0)
193169695Skan    alignment = (int) DEFAULT_ALIGNMENT;
194169695Skan  if (size == 0)
195169695Skan    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
196169695Skan    {
197169695Skan      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
198169695Skan	 Use the values for range checking, because if range checking is off,
199169695Skan	 the extra bytes won't be missed terribly, but if range checking is on
200169695Skan	 and we used a larger request, a whole extra 4096 bytes would be
201169695Skan	 allocated.
202169695Skan
203169695Skan	 These number are irrelevant to the new GNU malloc.  I suspect it is
204169695Skan	 less sensitive to the size of the request.  */
205169695Skan      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
206169695Skan		    + 4 + DEFAULT_ROUNDING - 1)
207169695Skan		   & ~(DEFAULT_ROUNDING - 1));
208169695Skan      size = 4096 - extra;
209169695Skan    }
210169695Skan
211169695Skan  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
212169695Skan  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
213169695Skan  h->chunk_size = size;
214169695Skan  h->alignment_mask = alignment - 1;
215169695Skan  h->extra_arg = arg;
216169695Skan  h->use_extra_arg = 1;
217169695Skan
218169695Skan  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
219169695Skan  if (!chunk)
220169695Skan    (*obstack_alloc_failed_handler) ();
221169695Skan  h->next_free = h->object_base = chunk->contents;
222169695Skan  h->chunk_limit = chunk->limit
223169695Skan    = (char *) chunk + h->chunk_size;
224169695Skan  chunk->prev = 0;
225169695Skan  /* The initial chunk now contains no empty object.  */
226169695Skan  h->maybe_empty_object = 0;
227169695Skan  h->alloc_failed = 0;
228169695Skan  return 1;
229169695Skan}
230169695Skan
231169695Skan/* Allocate a new current chunk for the obstack *H
232169695Skan   on the assumption that LENGTH bytes need to be added
233169695Skan   to the current object, or a new object of length LENGTH allocated.
234169695Skan   Copies any partial object from the end of the old chunk
235169695Skan   to the beginning of the new one.  */
236169695Skan
237169695Skanvoid
238169695Skan_obstack_newchunk (struct obstack *h, int length)
239169695Skan{
240169695Skan  register struct _obstack_chunk *old_chunk = h->chunk;
241169695Skan  register struct _obstack_chunk *new_chunk;
242169695Skan  register long	new_size;
243169695Skan  register long obj_size = h->next_free - h->object_base;
244169695Skan  register long i;
245169695Skan  long already;
246169695Skan
247169695Skan  /* Compute size for new chunk.  */
248169695Skan  new_size = (obj_size + length) + (obj_size >> 3) + 100;
249169695Skan  if (new_size < h->chunk_size)
250169695Skan    new_size = h->chunk_size;
251169695Skan
252169695Skan  /* Allocate and initialize the new chunk.  */
253169695Skan  new_chunk = CALL_CHUNKFUN (h, new_size);
254169695Skan  if (!new_chunk)
255169695Skan    (*obstack_alloc_failed_handler) ();
256169695Skan  h->chunk = new_chunk;
257169695Skan  new_chunk->prev = old_chunk;
258169695Skan  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
259169695Skan
260169695Skan  /* Move the existing object to the new chunk.
261169695Skan     Word at a time is fast and is safe if the object
262169695Skan     is sufficiently aligned.  */
263169695Skan  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
264169695Skan    {
265169695Skan      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
266169695Skan	   i >= 0; i--)
267169695Skan	((COPYING_UNIT *)new_chunk->contents)[i]
268169695Skan	  = ((COPYING_UNIT *)h->object_base)[i];
269169695Skan      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
270169695Skan	 but that can cross a page boundary on a machine
271169695Skan	 which does not do strict alignment for COPYING_UNITS.  */
272169695Skan      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
273169695Skan    }
274169695Skan  else
275169695Skan    already = 0;
276169695Skan  /* Copy remaining bytes one by one.  */
277169695Skan  for (i = already; i < obj_size; i++)
278169695Skan    new_chunk->contents[i] = h->object_base[i];
279169695Skan
280169695Skan  /* If the object just copied was the only data in OLD_CHUNK,
281169695Skan     free that chunk and remove it from the chain.
282169695Skan     But not if that chunk might contain an empty object.  */
283169695Skan  if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
284169695Skan    {
285169695Skan      new_chunk->prev = old_chunk->prev;
286169695Skan      CALL_FREEFUN (h, old_chunk);
287169695Skan    }
288169695Skan
289169695Skan  h->object_base = new_chunk->contents;
290169695Skan  h->next_free = h->object_base + obj_size;
291169695Skan  /* The new chunk certainly contains no empty object yet.  */
292169695Skan  h->maybe_empty_object = 0;
293169695Skan}
294169695Skan
295169695Skan/* Return nonzero if object OBJ has been allocated from obstack H.
296169695Skan   This is here for debugging.
297169695Skan   If you use it in a program, you are probably losing.  */
298169695Skan
299169695Skan/* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
300169695Skan   obstack.h because it is just for debugging.  */
301169695Skanint _obstack_allocated_p (struct obstack *h, POINTER obj);
302169695Skan
303169695Skanint
304169695Skan_obstack_allocated_p (struct obstack *h, POINTER obj)
305169695Skan{
306169695Skan  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
307169695Skan  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
308169695Skan
309169695Skan  lp = (h)->chunk;
310169695Skan  /* We use >= rather than > since the object cannot be exactly at
311169695Skan     the beginning of the chunk but might be an empty object exactly
312169695Skan     at the end of an adjacent chunk.  */
313169695Skan  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
314169695Skan    {
315169695Skan      plp = lp->prev;
316169695Skan      lp = plp;
317169695Skan    }
318169695Skan  return lp != 0;
319169695Skan}
320169695Skan
321169695Skan/* Free objects in obstack H, including OBJ and everything allocate
322169695Skan   more recently than OBJ.  If OBJ is zero, free everything in H.  */
323169695Skan
324169695Skan#undef obstack_free
325169695Skan
326169695Skan/* This function has two names with identical definitions.
327169695Skan   This is the first one, called from non-ANSI code.  */
328169695Skan
329169695Skanvoid
330169695Skan_obstack_free (struct obstack *h, POINTER obj)
331169695Skan{
332169695Skan  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
333169695Skan  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
334169695Skan
335169695Skan  lp = h->chunk;
336169695Skan  /* We use >= because there cannot be an object at the beginning of a chunk.
337169695Skan     But there can be an empty object at that address
338169695Skan     at the end of another chunk.  */
339169695Skan  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
340169695Skan    {
341169695Skan      plp = lp->prev;
342169695Skan      CALL_FREEFUN (h, lp);
343169695Skan      lp = plp;
344169695Skan      /* If we switch chunks, we can't tell whether the new current
345169695Skan	 chunk contains an empty object, so assume that it may.  */
346169695Skan      h->maybe_empty_object = 1;
347169695Skan    }
348169695Skan  if (lp)
349169695Skan    {
350169695Skan      h->object_base = h->next_free = (char *) (obj);
351169695Skan      h->chunk_limit = lp->limit;
352169695Skan      h->chunk = lp;
353169695Skan    }
354169695Skan  else if (obj != 0)
355169695Skan    /* obj is not in any of the chunks! */
356169695Skan    abort ();
357169695Skan}
358169695Skan
359169695Skan/* This function is used from ANSI code.  */
360169695Skan
361169695Skanvoid
362169695Skanobstack_free (struct obstack *h, POINTER obj)
363169695Skan{
364169695Skan  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
365169695Skan  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
366169695Skan
367169695Skan  lp = h->chunk;
368169695Skan  /* We use >= because there cannot be an object at the beginning of a chunk.
369169695Skan     But there can be an empty object at that address
370169695Skan     at the end of another chunk.  */
371169695Skan  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
372169695Skan    {
373169695Skan      plp = lp->prev;
374169695Skan      CALL_FREEFUN (h, lp);
375169695Skan      lp = plp;
376169695Skan      /* If we switch chunks, we can't tell whether the new current
377169695Skan	 chunk contains an empty object, so assume that it may.  */
378169695Skan      h->maybe_empty_object = 1;
379169695Skan    }
380169695Skan  if (lp)
381169695Skan    {
382169695Skan      h->object_base = h->next_free = (char *) (obj);
383169695Skan      h->chunk_limit = lp->limit;
384169695Skan      h->chunk = lp;
385169695Skan    }
386169695Skan  else if (obj != 0)
387169695Skan    /* obj is not in any of the chunks! */
388169695Skan    abort ();
389169695Skan}
390169695Skan
391169695Skanint
392169695Skan_obstack_memory_used (struct obstack *h)
393169695Skan{
394169695Skan  register struct _obstack_chunk* lp;
395169695Skan  register int nbytes = 0;
396169695Skan
397169695Skan  for (lp = h->chunk; lp != 0; lp = lp->prev)
398169695Skan    {
399169695Skan      nbytes += lp->limit - (char *) lp;
400169695Skan    }
401169695Skan  return nbytes;
402169695Skan}
403169695Skan
404169695Skan/* Define the error handler.  */
405169695Skan#ifndef _
406169695Skan# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
407169695Skan#  include <libintl.h>
408169695Skan#  ifndef _
409169695Skan#   define _(Str) gettext (Str)
410169695Skan#  endif
411169695Skan# else
412169695Skan#  define _(Str) (Str)
413169695Skan# endif
414169695Skan#endif
415169695Skan
416169695Skanstatic void
417169695Skanprint_and_abort (void)
418169695Skan{
419169695Skan  fputs (_("memory exhausted\n"), stderr);
420169695Skan  exit (obstack_exit_failure);
421169695Skan}
422169695Skan
423169695Skan#if 0
424169695Skan/* These are now turned off because the applications do not use it
425169695Skan   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
426169695Skan
427169695Skan/* Now define the functional versions of the obstack macros.
428169695Skan   Define them to simply use the corresponding macros to do the job.  */
429169695Skan
430169695Skan/* The function names appear in parentheses in order to prevent
431169695Skan   the macro-definitions of the names from being expanded there.  */
432169695Skan
433169695SkanPOINTER (obstack_base) (struct obstack *obstack)
434169695Skan{
435169695Skan  return obstack_base (obstack);
436169695Skan}
437169695Skan
438169695SkanPOINTER (obstack_next_free) (struct obstack *obstack)
439169695Skan{
440169695Skan  return obstack_next_free (obstack);
441169695Skan}
442169695Skan
443169695Skanint (obstack_object_size) (struct obstack *obstack)
444169695Skan{
445169695Skan  return obstack_object_size (obstack);
446169695Skan}
447169695Skan
448169695Skanint (obstack_room) (struct obstack *obstack)
449169695Skan{
450169695Skan  return obstack_room (obstack);
451169695Skan}
452169695Skan
453169695Skanint (obstack_make_room) (struct obstack *obstack, int length)
454169695Skan{
455169695Skan  return obstack_make_room (obstack, length);
456169695Skan}
457169695Skan
458169695Skanvoid (obstack_grow) (struct obstack *obstack, POINTER pointer, int length)
459169695Skan{
460169695Skan  obstack_grow (obstack, pointer, length);
461169695Skan}
462169695Skan
463169695Skanvoid (obstack_grow0) (struct obstack *obstack, POINTER pointer, int length)
464169695Skan{
465169695Skan  obstack_grow0 (obstack, pointer, length);
466169695Skan}
467169695Skan
468169695Skanvoid (obstack_1grow) (struct obstack *obstack, int character)
469169695Skan{
470169695Skan  obstack_1grow (obstack, character);
471169695Skan}
472169695Skan
473169695Skanvoid (obstack_blank) (struct obstack *obstack, int length)
474169695Skan{
475169695Skan  obstack_blank (obstack, length);
476169695Skan}
477169695Skan
478169695Skanvoid (obstack_1grow_fast) (struct obstack *obstack, int character)
479169695Skan{
480169695Skan  obstack_1grow_fast (obstack, character);
481169695Skan}
482169695Skan
483169695Skanvoid (obstack_blank_fast) (struct obstack *obstack, int length)
484169695Skan{
485169695Skan  obstack_blank_fast (obstack, length);
486169695Skan}
487169695Skan
488169695SkanPOINTER (obstack_finish) (struct obstack *obstack)
489169695Skan{
490169695Skan  return obstack_finish (obstack);
491169695Skan}
492169695Skan
493169695SkanPOINTER (obstack_alloc) (struct obstack *obstack, int length)
494169695Skan{
495169695Skan  return obstack_alloc (obstack, length);
496169695Skan}
497169695Skan
498169695SkanPOINTER (obstack_copy) (struct obstack *obstack, POINTER pointer, int length)
499169695Skan{
500169695Skan  return obstack_copy (obstack, pointer, length);
501169695Skan}
502169695Skan
503169695SkanPOINTER (obstack_copy0) (struct obstack *obstack, POINTER pointer, int length)
504169695Skan{
505169695Skan  return obstack_copy0 (obstack, pointer, length);
506169695Skan}
507169695Skan
508169695Skan#endif /* 0 */
509169695Skan
510169695Skan#endif	/* !ELIDE_CODE */
511