156918Sru/* obstack.c - subroutines used implicitly by object stack macros
256918Sru   Copyright (C) 1988-1994,96,97,98,99 Free Software Foundation, Inc.
353451Speter
456918Sru   This file is part of the GNU C Library.  Its master source is NOT part of
553475Sobrien   the C library, however.  The master source lives in /gd/gnu/lib.
653475Sobrien
756918Sru   The GNU C Library is free software; you can redistribute it and/or
856918Sru   modify it under the terms of the GNU Library General Public License as
956918Sru   published by the Free Software Foundation; either version 2 of the
1056918Sru   License, or (at your option) any later version.
1153475Sobrien
1256918Sru   The GNU C Library is distributed in the hope that it will be useful,
1356918Sru   but WITHOUT ANY WARRANTY; without even the implied warranty of
1456918Sru   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1556918Sru   Library General Public License for more details.
1653451Speter
1756918Sru   You should have received a copy of the GNU Library General Public
1856918Sru   License along with the GNU C Library; see the file COPYING.LIB.  If not,
1956918Sru   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
2056918Sru   Boston, MA 02111-1307, USA.  */
2153451Speter
2253475Sobrien#ifdef HAVE_CONFIG_H
2353475Sobrien#include <config.h>
2453475Sobrien#endif
2553475Sobrien
2653451Speter#include "obstack.h"
2753451Speter
2853475Sobrien/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
2953475Sobrien   incremented whenever callers compiled using an old obstack.h can no
3053475Sobrien   longer properly call the functions in this obstack.c.  */
3153475Sobrien#define OBSTACK_INTERFACE_VERSION 1
3253451Speter
3353451Speter/* Comment out all this code if we are using the GNU C Library, and are not
3453475Sobrien   actually compiling the library itself, and the installed library
3553475Sobrien   supports the same library interface we do.  This code is part of the GNU
3653475Sobrien   C Library, but also included in many other GNU distributions.  Compiling
3753451Speter   and linking in this code is a waste when using the GNU C library
3853451Speter   (especially if it is a shared library).  Rather than having every GNU
3953475Sobrien   program understand `configure --with-gnu-libc' and omit the object
4053475Sobrien   files, it is simpler to just do this in the source for each such file.  */
4153451Speter
4253475Sobrien#include <stdio.h>		/* Random thing to get __GNU_LIBRARY__.  */
4353475Sobrien#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
4453475Sobrien#include <gnu-versions.h>
4553475Sobrien#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
4653475Sobrien#define ELIDE_CODE
4753475Sobrien#endif
4853475Sobrien#endif
4953451Speter
5053451Speter
5153475Sobrien#ifndef ELIDE_CODE
5253475Sobrien
5353475Sobrien
5453475Sobrien#if defined (__STDC__) && __STDC__
5553451Speter#define POINTER void *
5653451Speter#else
5753451Speter#define POINTER char *
5853451Speter#endif
5953451Speter
6053451Speter/* Determine default alignment.  */
6153451Speterstruct fooalign {char x; double d;};
6253451Speter#define DEFAULT_ALIGNMENT  \
6353475Sobrien  ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
6453451Speter/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
6553451Speter   But in fact it might be less smart and round addresses to as much as
6653451Speter   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
6753451Speterunion fooround {long x; double d;};
6853451Speter#define DEFAULT_ROUNDING (sizeof (union fooround))
6953451Speter
7053451Speter/* When we copy a long block of data, this is the unit to do it with.
7153451Speter   On some machines, copying successive ints does not work;
7253451Speter   in such a case, redefine COPYING_UNIT to `long' (if that works)
7353451Speter   or `char' as a last resort.  */
7453451Speter#ifndef COPYING_UNIT
7553451Speter#define COPYING_UNIT int
7653451Speter#endif
7753451Speter
7853475Sobrien
7953475Sobrien/* The functions allocating more room by calling `obstack_chunk_alloc'
8053475Sobrien   jump to the handler pointed to by `obstack_alloc_failed_handler'.
8156918Sru   This can be set to a user defined function which should either
8256918Sru   abort gracefully or use longjump - but shouldn't return.  This
8356918Sru   variable by default points to the internal function
8453475Sobrien   `print_and_abort'.  */
8553475Sobrien#if defined (__STDC__) && __STDC__
8653475Sobrienstatic void print_and_abort (void);
8753475Sobrienvoid (*obstack_alloc_failed_handler) (void) = print_and_abort;
8853475Sobrien#else
8953475Sobrienstatic void print_and_abort ();
9053475Sobrienvoid (*obstack_alloc_failed_handler) () = print_and_abort;
9153475Sobrien#endif
9253475Sobrien
9353475Sobrien/* Exit value used when `print_and_abort' is used.  */
9453475Sobrien#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
9553475Sobrien#include <stdlib.h>
9653475Sobrien#endif
9753475Sobrien#ifndef EXIT_FAILURE
9853475Sobrien#define EXIT_FAILURE 1
9953475Sobrien#endif
10053475Sobrienint obstack_exit_failure = EXIT_FAILURE;
10153475Sobrien
10253451Speter/* The non-GNU-C macros copy the obstack into this global variable
10353451Speter   to avoid multiple evaluation.  */
10453451Speter
10553451Speterstruct obstack *_obstack;
10653451Speter
10753451Speter/* Define a macro that either calls functions with the traditional malloc/free
10853451Speter   calling interface, or calls functions with the mmalloc/mfree interface
10953451Speter   (that adds an extra first argument), based on the state of use_extra_arg.
11053451Speter   For free, do not use ?:, since some compilers, like the MIPS compilers,
11153451Speter   do not allow (expr) ? void : void.  */
11253451Speter
11353475Sobrien#if defined (__STDC__) && __STDC__
11453451Speter#define CALL_CHUNKFUN(h, size) \
11553451Speter  (((h) -> use_extra_arg) \
11653451Speter   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
11753475Sobrien   : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
11853451Speter
11953451Speter#define CALL_FREEFUN(h, old_chunk) \
12053451Speter  do { \
12153451Speter    if ((h) -> use_extra_arg) \
12253451Speter      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
12353451Speter    else \
12453475Sobrien      (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
12553451Speter  } while (0)
12653475Sobrien#else
12753475Sobrien#define CALL_CHUNKFUN(h, size) \
12853475Sobrien  (((h) -> use_extra_arg) \
12953475Sobrien   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
13053475Sobrien   : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
13153451Speter
13253475Sobrien#define CALL_FREEFUN(h, old_chunk) \
13353475Sobrien  do { \
13453475Sobrien    if ((h) -> use_extra_arg) \
13553475Sobrien      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
13653475Sobrien    else \
13753475Sobrien      (*(void (*) ()) (h)->freefun) ((old_chunk)); \
13853475Sobrien  } while (0)
13953475Sobrien#endif
14053475Sobrien
14153451Speter
14253451Speter/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
14353451Speter   Objects start on multiples of ALIGNMENT (0 means use default).
14453451Speter   CHUNKFUN is the function to use to allocate chunks,
14553475Sobrien   and FREEFUN the function to free them.
14653451Speter
14756918Sru   Return nonzero if successful, calls obstack_alloc_failed_handler if
14856918Sru   allocation fails.  */
14953475Sobrien
15053475Sobrienint
15153451Speter_obstack_begin (h, size, alignment, chunkfun, freefun)
15253451Speter     struct obstack *h;
15353451Speter     int size;
15453451Speter     int alignment;
15553475Sobrien#if defined (__STDC__) && __STDC__
15653475Sobrien     POINTER (*chunkfun) (long);
15753475Sobrien     void (*freefun) (void *);
15853475Sobrien#else
15953451Speter     POINTER (*chunkfun) ();
16053451Speter     void (*freefun) ();
16153475Sobrien#endif
16253451Speter{
16353475Sobrien  register struct _obstack_chunk *chunk; /* points to new chunk */
16453451Speter
16553451Speter  if (alignment == 0)
16653475Sobrien    alignment = (int) DEFAULT_ALIGNMENT;
16753451Speter  if (size == 0)
16853451Speter    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
16953451Speter    {
17053451Speter      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
17153451Speter	 Use the values for range checking, because if range checking is off,
17253451Speter	 the extra bytes won't be missed terribly, but if range checking is on
17353451Speter	 and we used a larger request, a whole extra 4096 bytes would be
17453451Speter	 allocated.
17553451Speter
17653451Speter	 These number are irrelevant to the new GNU malloc.  I suspect it is
17753451Speter	 less sensitive to the size of the request.  */
17853451Speter      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
17953451Speter		    + 4 + DEFAULT_ROUNDING - 1)
18053451Speter		   & ~(DEFAULT_ROUNDING - 1));
18153451Speter      size = 4096 - extra;
18253451Speter    }
18353451Speter
18453475Sobrien#if defined (__STDC__) && __STDC__
18553475Sobrien  h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
18653475Sobrien  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
18753475Sobrien#else
18853451Speter  h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
18953451Speter  h->freefun = freefun;
19053475Sobrien#endif
19153451Speter  h->chunk_size = size;
19253451Speter  h->alignment_mask = alignment - 1;
19353451Speter  h->use_extra_arg = 0;
19453451Speter
19553451Speter  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
19653475Sobrien  if (!chunk)
19753475Sobrien    (*obstack_alloc_failed_handler) ();
19853451Speter  h->next_free = h->object_base = chunk->contents;
19953451Speter  h->chunk_limit = chunk->limit
20053451Speter    = (char *) chunk + h->chunk_size;
20153451Speter  chunk->prev = 0;
20253451Speter  /* The initial chunk now contains no empty object.  */
20353451Speter  h->maybe_empty_object = 0;
20453475Sobrien  h->alloc_failed = 0;
20553475Sobrien  return 1;
20653451Speter}
20753451Speter
20853475Sobrienint
20953451Speter_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
21053451Speter     struct obstack *h;
21153451Speter     int size;
21253451Speter     int alignment;
21353475Sobrien#if defined (__STDC__) && __STDC__
21453475Sobrien     POINTER (*chunkfun) (POINTER, long);
21553475Sobrien     void (*freefun) (POINTER, POINTER);
21653475Sobrien#else
21753451Speter     POINTER (*chunkfun) ();
21853451Speter     void (*freefun) ();
21953475Sobrien#endif
22053451Speter     POINTER arg;
22153451Speter{
22253475Sobrien  register struct _obstack_chunk *chunk; /* points to new chunk */
22353451Speter
22453451Speter  if (alignment == 0)
22553475Sobrien    alignment = (int) DEFAULT_ALIGNMENT;
22653451Speter  if (size == 0)
22753451Speter    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
22853451Speter    {
22953451Speter      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
23053451Speter	 Use the values for range checking, because if range checking is off,
23153451Speter	 the extra bytes won't be missed terribly, but if range checking is on
23253451Speter	 and we used a larger request, a whole extra 4096 bytes would be
23353451Speter	 allocated.
23453451Speter
23553451Speter	 These number are irrelevant to the new GNU malloc.  I suspect it is
23653451Speter	 less sensitive to the size of the request.  */
23753451Speter      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
23853451Speter		    + 4 + DEFAULT_ROUNDING - 1)
23953451Speter		   & ~(DEFAULT_ROUNDING - 1));
24053451Speter      size = 4096 - extra;
24153451Speter    }
24253451Speter
24353475Sobrien#if defined(__STDC__) && __STDC__
24453475Sobrien  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
24553475Sobrien  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
24653475Sobrien#else
24753451Speter  h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
24853451Speter  h->freefun = freefun;
24953475Sobrien#endif
25053451Speter  h->chunk_size = size;
25153451Speter  h->alignment_mask = alignment - 1;
25253451Speter  h->extra_arg = arg;
25353451Speter  h->use_extra_arg = 1;
25453451Speter
25553451Speter  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
25653475Sobrien  if (!chunk)
25753475Sobrien    (*obstack_alloc_failed_handler) ();
25853451Speter  h->next_free = h->object_base = chunk->contents;
25953451Speter  h->chunk_limit = chunk->limit
26053451Speter    = (char *) chunk + h->chunk_size;
26153451Speter  chunk->prev = 0;
26253451Speter  /* The initial chunk now contains no empty object.  */
26353451Speter  h->maybe_empty_object = 0;
26453475Sobrien  h->alloc_failed = 0;
26553475Sobrien  return 1;
26653451Speter}
26753451Speter
26853451Speter/* Allocate a new current chunk for the obstack *H
26953451Speter   on the assumption that LENGTH bytes need to be added
27053451Speter   to the current object, or a new object of length LENGTH allocated.
27153451Speter   Copies any partial object from the end of the old chunk
27253451Speter   to the beginning of the new one.  */
27353451Speter
27453451Spetervoid
27553451Speter_obstack_newchunk (h, length)
27653451Speter     struct obstack *h;
27753451Speter     int length;
27853451Speter{
27953475Sobrien  register struct _obstack_chunk *old_chunk = h->chunk;
28053475Sobrien  register struct _obstack_chunk *new_chunk;
28153451Speter  register long	new_size;
28253475Sobrien  register long obj_size = h->next_free - h->object_base;
28353475Sobrien  register long i;
28453475Sobrien  long already;
28553451Speter
28653451Speter  /* Compute size for new chunk.  */
28753451Speter  new_size = (obj_size + length) + (obj_size >> 3) + 100;
28853451Speter  if (new_size < h->chunk_size)
28953451Speter    new_size = h->chunk_size;
29053451Speter
29153451Speter  /* Allocate and initialize the new chunk.  */
29253475Sobrien  new_chunk = CALL_CHUNKFUN (h, new_size);
29353475Sobrien  if (!new_chunk)
29453475Sobrien    (*obstack_alloc_failed_handler) ();
29553475Sobrien  h->chunk = new_chunk;
29653451Speter  new_chunk->prev = old_chunk;
29753451Speter  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
29853451Speter
29953451Speter  /* Move the existing object to the new chunk.
30053451Speter     Word at a time is fast and is safe if the object
30153451Speter     is sufficiently aligned.  */
30253451Speter  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
30353451Speter    {
30453451Speter      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
30553451Speter	   i >= 0; i--)
30653451Speter	((COPYING_UNIT *)new_chunk->contents)[i]
30753451Speter	  = ((COPYING_UNIT *)h->object_base)[i];
30853451Speter      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
30953451Speter	 but that can cross a page boundary on a machine
31053451Speter	 which does not do strict alignment for COPYING_UNITS.  */
31153451Speter      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
31253451Speter    }
31353451Speter  else
31453451Speter    already = 0;
31553451Speter  /* Copy remaining bytes one by one.  */
31653451Speter  for (i = already; i < obj_size; i++)
31753451Speter    new_chunk->contents[i] = h->object_base[i];
31853451Speter
31953451Speter  /* If the object just copied was the only data in OLD_CHUNK,
32053451Speter     free that chunk and remove it from the chain.
32153451Speter     But not if that chunk might contain an empty object.  */
32253451Speter  if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
32353451Speter    {
32453451Speter      new_chunk->prev = old_chunk->prev;
32553451Speter      CALL_FREEFUN (h, old_chunk);
32653451Speter    }
32753451Speter
32853451Speter  h->object_base = new_chunk->contents;
32953451Speter  h->next_free = h->object_base + obj_size;
33053451Speter  /* The new chunk certainly contains no empty object yet.  */
33153451Speter  h->maybe_empty_object = 0;
33253451Speter}
33353451Speter
33453451Speter/* Return nonzero if object OBJ has been allocated from obstack H.
33553451Speter   This is here for debugging.
33653451Speter   If you use it in a program, you are probably losing.  */
33753451Speter
33853475Sobrien#if defined (__STDC__) && __STDC__
33953475Sobrien/* Suppress -Wmissing-prototypes warning.  We don't want to declare this in
34053475Sobrien   obstack.h because it is just for debugging.  */
34153475Sobrienint _obstack_allocated_p (struct obstack *h, POINTER obj);
34253475Sobrien#endif
34353475Sobrien
34453451Speterint
34553451Speter_obstack_allocated_p (h, obj)
34653451Speter     struct obstack *h;
34753451Speter     POINTER obj;
34853451Speter{
34953475Sobrien  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
35053475Sobrien  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
35153451Speter
35253451Speter  lp = (h)->chunk;
35353451Speter  /* We use >= rather than > since the object cannot be exactly at
35453451Speter     the beginning of the chunk but might be an empty object exactly
35553475Sobrien     at the end of an adjacent chunk.  */
35653475Sobrien  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
35753451Speter    {
35853451Speter      plp = lp->prev;
35953451Speter      lp = plp;
36053451Speter    }
36153451Speter  return lp != 0;
36253451Speter}
36353451Speter
36453451Speter/* Free objects in obstack H, including OBJ and everything allocate
36553451Speter   more recently than OBJ.  If OBJ is zero, free everything in H.  */
36653451Speter
36753451Speter#undef obstack_free
36853451Speter
36953451Speter/* This function has two names with identical definitions.
37053451Speter   This is the first one, called from non-ANSI code.  */
37153451Speter
37253451Spetervoid
37353451Speter_obstack_free (h, obj)
37453451Speter     struct obstack *h;
37553451Speter     POINTER obj;
37653451Speter{
37753475Sobrien  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
37853475Sobrien  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
37953451Speter
38053451Speter  lp = h->chunk;
38153451Speter  /* We use >= because there cannot be an object at the beginning of a chunk.
38253451Speter     But there can be an empty object at that address
38353451Speter     at the end of another chunk.  */
38453475Sobrien  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
38553451Speter    {
38653451Speter      plp = lp->prev;
38753451Speter      CALL_FREEFUN (h, lp);
38853451Speter      lp = plp;
38953451Speter      /* If we switch chunks, we can't tell whether the new current
39053451Speter	 chunk contains an empty object, so assume that it may.  */
39153451Speter      h->maybe_empty_object = 1;
39253451Speter    }
39353451Speter  if (lp)
39453451Speter    {
39553475Sobrien      h->object_base = h->next_free = (char *) (obj);
39653451Speter      h->chunk_limit = lp->limit;
39753451Speter      h->chunk = lp;
39853451Speter    }
39953451Speter  else if (obj != 0)
40053451Speter    /* obj is not in any of the chunks! */
40153451Speter    abort ();
40253451Speter}
40353451Speter
40453451Speter/* This function is used from ANSI code.  */
40553451Speter
40653451Spetervoid
40753451Speterobstack_free (h, obj)
40853451Speter     struct obstack *h;
40953451Speter     POINTER obj;
41053451Speter{
41153475Sobrien  register struct _obstack_chunk *lp;	/* below addr of any objects in this chunk */
41253475Sobrien  register struct _obstack_chunk *plp;	/* point to previous chunk if any */
41353451Speter
41453451Speter  lp = h->chunk;
41553451Speter  /* We use >= because there cannot be an object at the beginning of a chunk.
41653451Speter     But there can be an empty object at that address
41753451Speter     at the end of another chunk.  */
41853475Sobrien  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
41953451Speter    {
42053451Speter      plp = lp->prev;
42153451Speter      CALL_FREEFUN (h, lp);
42253451Speter      lp = plp;
42353451Speter      /* If we switch chunks, we can't tell whether the new current
42453451Speter	 chunk contains an empty object, so assume that it may.  */
42553451Speter      h->maybe_empty_object = 1;
42653451Speter    }
42753451Speter  if (lp)
42853451Speter    {
42953475Sobrien      h->object_base = h->next_free = (char *) (obj);
43053451Speter      h->chunk_limit = lp->limit;
43153451Speter      h->chunk = lp;
43253451Speter    }
43353451Speter  else if (obj != 0)
43453451Speter    /* obj is not in any of the chunks! */
43553451Speter    abort ();
43653451Speter}
43753451Speter
43853475Sobrienint
43953475Sobrien_obstack_memory_used (h)
44053475Sobrien     struct obstack *h;
44153475Sobrien{
44253475Sobrien  register struct _obstack_chunk* lp;
44353475Sobrien  register int nbytes = 0;
44453475Sobrien
44553475Sobrien  for (lp = h->chunk; lp != 0; lp = lp->prev)
44653475Sobrien    {
44753475Sobrien      nbytes += lp->limit - (char *) lp;
44853475Sobrien    }
44953475Sobrien  return nbytes;
45053475Sobrien}
45153475Sobrien
45253475Sobrien/* Define the error handler.  */
45353475Sobrien#ifndef _
45453475Sobrien# ifdef HAVE_LIBINTL_H
45553475Sobrien#  include <libintl.h>
45653475Sobrien#  ifndef _
45753475Sobrien#   define _(Str) gettext (Str)
45853475Sobrien#  endif
45953475Sobrien# else
46053475Sobrien#  define _(Str) (Str)
46153475Sobrien# endif
46253475Sobrien#endif
46356918Sru#if defined _LIBC && defined USE_IN_LIBIO
46456918Sru# include <libio/iolibio.h>
46556918Sru# define fputs(s, f) _IO_fputs (s, f)
46656918Sru#endif
46753475Sobrien
46853475Sobrienstatic void
46953475Sobrienprint_and_abort ()
47053475Sobrien{
47156918Sru  fputs (_("memory exhausted"), stderr);
47256918Sru  fputc ('\n', stderr);
47353475Sobrien  exit (obstack_exit_failure);
47453475Sobrien}
47553475Sobrien
47653451Speter#if 0
47753451Speter/* These are now turned off because the applications do not use it
47853451Speter   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
47953451Speter
48053451Speter/* Now define the functional versions of the obstack macros.
48153451Speter   Define them to simply use the corresponding macros to do the job.  */
48253451Speter
48353475Sobrien#if defined (__STDC__) && __STDC__
48453451Speter/* These function definitions do not work with non-ANSI preprocessors;
48553451Speter   they won't pass through the macro names in parentheses.  */
48653451Speter
48753451Speter/* The function names appear in parentheses in order to prevent
48853451Speter   the macro-definitions of the names from being expanded there.  */
48953451Speter
49053451SpeterPOINTER (obstack_base) (obstack)
49153451Speter     struct obstack *obstack;
49253451Speter{
49353451Speter  return obstack_base (obstack);
49453451Speter}
49553451Speter
49653451SpeterPOINTER (obstack_next_free) (obstack)
49753451Speter     struct obstack *obstack;
49853451Speter{
49953451Speter  return obstack_next_free (obstack);
50053451Speter}
50153451Speter
50253451Speterint (obstack_object_size) (obstack)
50353451Speter     struct obstack *obstack;
50453451Speter{
50553451Speter  return obstack_object_size (obstack);
50653451Speter}
50753451Speter
50853451Speterint (obstack_room) (obstack)
50953451Speter     struct obstack *obstack;
51053451Speter{
51153451Speter  return obstack_room (obstack);
51253451Speter}
51353451Speter
51453475Sobrienint (obstack_make_room) (obstack, length)
51553475Sobrien     struct obstack *obstack;
51653475Sobrien     int length;
51753475Sobrien{
51853475Sobrien  return obstack_make_room (obstack, length);
51953475Sobrien}
52053475Sobrien
52153451Spetervoid (obstack_grow) (obstack, pointer, length)
52253451Speter     struct obstack *obstack;
52353451Speter     POINTER pointer;
52453451Speter     int length;
52553451Speter{
52653451Speter  obstack_grow (obstack, pointer, length);
52753451Speter}
52853451Speter
52953451Spetervoid (obstack_grow0) (obstack, pointer, length)
53053451Speter     struct obstack *obstack;
53153451Speter     POINTER pointer;
53253451Speter     int length;
53353451Speter{
53453451Speter  obstack_grow0 (obstack, pointer, length);
53553451Speter}
53653451Speter
53753451Spetervoid (obstack_1grow) (obstack, character)
53853451Speter     struct obstack *obstack;
53953451Speter     int character;
54053451Speter{
54153451Speter  obstack_1grow (obstack, character);
54253451Speter}
54353451Speter
54453451Spetervoid (obstack_blank) (obstack, length)
54553451Speter     struct obstack *obstack;
54653451Speter     int length;
54753451Speter{
54853451Speter  obstack_blank (obstack, length);
54953451Speter}
55053451Speter
55153451Spetervoid (obstack_1grow_fast) (obstack, character)
55253451Speter     struct obstack *obstack;
55353451Speter     int character;
55453451Speter{
55553451Speter  obstack_1grow_fast (obstack, character);
55653451Speter}
55753451Speter
55853451Spetervoid (obstack_blank_fast) (obstack, length)
55953451Speter     struct obstack *obstack;
56053451Speter     int length;
56153451Speter{
56253451Speter  obstack_blank_fast (obstack, length);
56353451Speter}
56453451Speter
56553451SpeterPOINTER (obstack_finish) (obstack)
56653451Speter     struct obstack *obstack;
56753451Speter{
56853451Speter  return obstack_finish (obstack);
56953451Speter}
57053451Speter
57153451SpeterPOINTER (obstack_alloc) (obstack, length)
57253451Speter     struct obstack *obstack;
57353451Speter     int length;
57453451Speter{
57553451Speter  return obstack_alloc (obstack, length);
57653451Speter}
57753451Speter
57853451SpeterPOINTER (obstack_copy) (obstack, pointer, length)
57953451Speter     struct obstack *obstack;
58053451Speter     POINTER pointer;
58153451Speter     int length;
58253451Speter{
58353451Speter  return obstack_copy (obstack, pointer, length);
58453451Speter}
58553451Speter
58653451SpeterPOINTER (obstack_copy0) (obstack, pointer, length)
58753451Speter     struct obstack *obstack;
58853451Speter     POINTER pointer;
58953451Speter     int length;
59053451Speter{
59153451Speter  return obstack_copy0 (obstack, pointer, length);
59253451Speter}
59353451Speter
59453451Speter#endif /* __STDC__ */
59553451Speter
59653451Speter#endif /* 0 */
59753451Speter
59853475Sobrien#endif	/* !ELIDE_CODE */
599