obstack.c revision 53451
153451Speter/* obstack.c - subroutines used implicitly by object stack macros
253451Speter   Copyright (C) 1988, 1993 Free Software Foundation, Inc.
353451Speter
453451SpeterThis program is free software; you can redistribute it and/or modify it
553451Speterunder the terms of the GNU General Public License as published by the
653451SpeterFree Software Foundation; either version 2, or (at your option) any
753451Speterlater version.
853451Speter
953451SpeterThis program is distributed in the hope that it will be useful,
1053451Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1153451SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1253451SpeterGNU General Public License for more details.
1353451Speter
1453451SpeterYou should have received a copy of the GNU General Public License
1553451Speteralong with this program; if not, write to the Free Software
1653451SpeterFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1753451Speter
1853451Speter#include "obstack.h"
1953451Speter
2053451Speter/* This is just to get __GNU_LIBRARY__ defined.  */
2153451Speter#include <stdio.h>
2253451Speter
2353451Speter/* Comment out all this code if we are using the GNU C Library, and are not
2453451Speter   actually compiling the library itself.  This code is part of the GNU C
2553451Speter   Library, but also included in many other GNU distributions.  Compiling
2653451Speter   and linking in this code is a waste when using the GNU C library
2753451Speter   (especially if it is a shared library).  Rather than having every GNU
2853451Speter   program understand `configure --with-gnu-libc' and omit the object files,
2953451Speter   it is simpler to just do this in the source for each such file.  */
3053451Speter
3153451Speter#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
3253451Speter
3353451Speter
3453451Speter#ifdef __STDC__
3553451Speter#define POINTER void *
3653451Speter#else
3753451Speter#define POINTER char *
3853451Speter#endif
3953451Speter
4053451Speter/* Determine default alignment.  */
4153451Speterstruct fooalign {char x; double d;};
4253451Speter#define DEFAULT_ALIGNMENT  \
4353451Speter  ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
4453451Speter/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
4553451Speter   But in fact it might be less smart and round addresses to as much as
4653451Speter   DEFAULT_ROUNDING.  So we prepare for it to do that.  */
4753451Speterunion fooround {long x; double d;};
4853451Speter#define DEFAULT_ROUNDING (sizeof (union fooround))
4953451Speter
5053451Speter/* When we copy a long block of data, this is the unit to do it with.
5153451Speter   On some machines, copying successive ints does not work;
5253451Speter   in such a case, redefine COPYING_UNIT to `long' (if that works)
5353451Speter   or `char' as a last resort.  */
5453451Speter#ifndef COPYING_UNIT
5553451Speter#define COPYING_UNIT int
5653451Speter#endif
5753451Speter
5853451Speter/* The non-GNU-C macros copy the obstack into this global variable
5953451Speter   to avoid multiple evaluation.  */
6053451Speter
6153451Speterstruct obstack *_obstack;
6253451Speter
6353451Speter/* Define a macro that either calls functions with the traditional malloc/free
6453451Speter   calling interface, or calls functions with the mmalloc/mfree interface
6553451Speter   (that adds an extra first argument), based on the state of use_extra_arg.
6653451Speter   For free, do not use ?:, since some compilers, like the MIPS compilers,
6753451Speter   do not allow (expr) ? void : void.  */
6853451Speter
6953451Speter#define CALL_CHUNKFUN(h, size) \
7053451Speter  (((h) -> use_extra_arg) \
7153451Speter   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
7253451Speter   : (*(h)->chunkfun) ((size)))
7353451Speter
7453451Speter#define CALL_FREEFUN(h, old_chunk) \
7553451Speter  do { \
7653451Speter    if ((h) -> use_extra_arg) \
7753451Speter      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
7853451Speter    else \
7953451Speter      (*(h)->freefun) ((old_chunk)); \
8053451Speter  } while (0)
8153451Speter
8253451Speter
8353451Speter/* Initialize an obstack H for use.  Specify chunk size SIZE (0 means default).
8453451Speter   Objects start on multiples of ALIGNMENT (0 means use default).
8553451Speter   CHUNKFUN is the function to use to allocate chunks,
8653451Speter   and FREEFUN the function to free them.  */
8753451Speter
8853451Spetervoid
8953451Speter_obstack_begin (h, size, alignment, chunkfun, freefun)
9053451Speter     struct obstack *h;
9153451Speter     int size;
9253451Speter     int alignment;
9353451Speter     POINTER (*chunkfun) ();
9453451Speter     void (*freefun) ();
9553451Speter{
9653451Speter  register struct _obstack_chunk* chunk; /* points to new chunk */
9753451Speter
9853451Speter  if (alignment == 0)
9953451Speter    alignment = DEFAULT_ALIGNMENT;
10053451Speter  if (size == 0)
10153451Speter    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
10253451Speter    {
10353451Speter      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
10453451Speter	 Use the values for range checking, because if range checking is off,
10553451Speter	 the extra bytes won't be missed terribly, but if range checking is on
10653451Speter	 and we used a larger request, a whole extra 4096 bytes would be
10753451Speter	 allocated.
10853451Speter
10953451Speter	 These number are irrelevant to the new GNU malloc.  I suspect it is
11053451Speter	 less sensitive to the size of the request.  */
11153451Speter      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
11253451Speter		    + 4 + DEFAULT_ROUNDING - 1)
11353451Speter		   & ~(DEFAULT_ROUNDING - 1));
11453451Speter      size = 4096 - extra;
11553451Speter    }
11653451Speter
11753451Speter  h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
11853451Speter  h->freefun = freefun;
11953451Speter  h->chunk_size = size;
12053451Speter  h->alignment_mask = alignment - 1;
12153451Speter  h->use_extra_arg = 0;
12253451Speter
12353451Speter  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
12453451Speter  h->next_free = h->object_base = chunk->contents;
12553451Speter  h->chunk_limit = chunk->limit
12653451Speter    = (char *) chunk + h->chunk_size;
12753451Speter  chunk->prev = 0;
12853451Speter  /* The initial chunk now contains no empty object.  */
12953451Speter  h->maybe_empty_object = 0;
13053451Speter}
13153451Speter
13253451Spetervoid
13353451Speter_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
13453451Speter     struct obstack *h;
13553451Speter     int size;
13653451Speter     int alignment;
13753451Speter     POINTER (*chunkfun) ();
13853451Speter     void (*freefun) ();
13953451Speter     POINTER arg;
14053451Speter{
14153451Speter  register struct _obstack_chunk* chunk; /* points to new chunk */
14253451Speter
14353451Speter  if (alignment == 0)
14453451Speter    alignment = DEFAULT_ALIGNMENT;
14553451Speter  if (size == 0)
14653451Speter    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
14753451Speter    {
14853451Speter      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
14953451Speter	 Use the values for range checking, because if range checking is off,
15053451Speter	 the extra bytes won't be missed terribly, but if range checking is on
15153451Speter	 and we used a larger request, a whole extra 4096 bytes would be
15253451Speter	 allocated.
15353451Speter
15453451Speter	 These number are irrelevant to the new GNU malloc.  I suspect it is
15553451Speter	 less sensitive to the size of the request.  */
15653451Speter      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
15753451Speter		    + 4 + DEFAULT_ROUNDING - 1)
15853451Speter		   & ~(DEFAULT_ROUNDING - 1));
15953451Speter      size = 4096 - extra;
16053451Speter    }
16153451Speter
16253451Speter  h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
16353451Speter  h->freefun = freefun;
16453451Speter  h->chunk_size = size;
16553451Speter  h->alignment_mask = alignment - 1;
16653451Speter  h->extra_arg = arg;
16753451Speter  h->use_extra_arg = 1;
16853451Speter
16953451Speter  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
17053451Speter  h->next_free = h->object_base = chunk->contents;
17153451Speter  h->chunk_limit = chunk->limit
17253451Speter    = (char *) chunk + h->chunk_size;
17353451Speter  chunk->prev = 0;
17453451Speter  /* The initial chunk now contains no empty object.  */
17553451Speter  h->maybe_empty_object = 0;
17653451Speter}
17753451Speter
17853451Speter/* Allocate a new current chunk for the obstack *H
17953451Speter   on the assumption that LENGTH bytes need to be added
18053451Speter   to the current object, or a new object of length LENGTH allocated.
18153451Speter   Copies any partial object from the end of the old chunk
18253451Speter   to the beginning of the new one.  */
18353451Speter
18453451Spetervoid
18553451Speter_obstack_newchunk (h, length)
18653451Speter     struct obstack *h;
18753451Speter     int length;
18853451Speter{
18953451Speter  register struct _obstack_chunk*	old_chunk = h->chunk;
19053451Speter  register struct _obstack_chunk*	new_chunk;
19153451Speter  register long	new_size;
19253451Speter  register int obj_size = h->next_free - h->object_base;
19353451Speter  register int i;
19453451Speter  int already;
19553451Speter
19653451Speter  /* Compute size for new chunk.  */
19753451Speter  new_size = (obj_size + length) + (obj_size >> 3) + 100;
19853451Speter  if (new_size < h->chunk_size)
19953451Speter    new_size = h->chunk_size;
20053451Speter
20153451Speter  /* Allocate and initialize the new chunk.  */
20253451Speter  new_chunk = h->chunk = CALL_CHUNKFUN (h, new_size);
20353451Speter  new_chunk->prev = old_chunk;
20453451Speter  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
20553451Speter
20653451Speter  /* Move the existing object to the new chunk.
20753451Speter     Word at a time is fast and is safe if the object
20853451Speter     is sufficiently aligned.  */
20953451Speter  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
21053451Speter    {
21153451Speter      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
21253451Speter	   i >= 0; i--)
21353451Speter	((COPYING_UNIT *)new_chunk->contents)[i]
21453451Speter	  = ((COPYING_UNIT *)h->object_base)[i];
21553451Speter      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
21653451Speter	 but that can cross a page boundary on a machine
21753451Speter	 which does not do strict alignment for COPYING_UNITS.  */
21853451Speter      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
21953451Speter    }
22053451Speter  else
22153451Speter    already = 0;
22253451Speter  /* Copy remaining bytes one by one.  */
22353451Speter  for (i = already; i < obj_size; i++)
22453451Speter    new_chunk->contents[i] = h->object_base[i];
22553451Speter
22653451Speter  /* If the object just copied was the only data in OLD_CHUNK,
22753451Speter     free that chunk and remove it from the chain.
22853451Speter     But not if that chunk might contain an empty object.  */
22953451Speter  if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
23053451Speter    {
23153451Speter      new_chunk->prev = old_chunk->prev;
23253451Speter      CALL_FREEFUN (h, old_chunk);
23353451Speter    }
23453451Speter
23553451Speter  h->object_base = new_chunk->contents;
23653451Speter  h->next_free = h->object_base + obj_size;
23753451Speter  /* The new chunk certainly contains no empty object yet.  */
23853451Speter  h->maybe_empty_object = 0;
23953451Speter}
24053451Speter
24153451Speter/* Return nonzero if object OBJ has been allocated from obstack H.
24253451Speter   This is here for debugging.
24353451Speter   If you use it in a program, you are probably losing.  */
24453451Speter
24553451Speterint
24653451Speter_obstack_allocated_p (h, obj)
24753451Speter     struct obstack *h;
24853451Speter     POINTER obj;
24953451Speter{
25053451Speter  register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
25153451Speter  register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
25253451Speter
25353451Speter  lp = (h)->chunk;
25453451Speter  /* We use >= rather than > since the object cannot be exactly at
25553451Speter     the beginning of the chunk but might be an empty object exactly
25653451Speter     at the end of an adjacent chunk. */
25753451Speter  while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
25853451Speter    {
25953451Speter      plp = lp->prev;
26053451Speter      lp = plp;
26153451Speter    }
26253451Speter  return lp != 0;
26353451Speter}
26453451Speter
26553451Speter/* Free objects in obstack H, including OBJ and everything allocate
26653451Speter   more recently than OBJ.  If OBJ is zero, free everything in H.  */
26753451Speter
26853451Speter#undef obstack_free
26953451Speter
27053451Speter/* This function has two names with identical definitions.
27153451Speter   This is the first one, called from non-ANSI code.  */
27253451Speter
27353451Spetervoid
27453451Speter_obstack_free (h, obj)
27553451Speter     struct obstack *h;
27653451Speter     POINTER obj;
27753451Speter{
27853451Speter  register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
27953451Speter  register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
28053451Speter
28153451Speter  lp = h->chunk;
28253451Speter  /* We use >= because there cannot be an object at the beginning of a chunk.
28353451Speter     But there can be an empty object at that address
28453451Speter     at the end of another chunk.  */
28553451Speter  while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
28653451Speter    {
28753451Speter      plp = lp->prev;
28853451Speter      CALL_FREEFUN (h, lp);
28953451Speter      lp = plp;
29053451Speter      /* If we switch chunks, we can't tell whether the new current
29153451Speter	 chunk contains an empty object, so assume that it may.  */
29253451Speter      h->maybe_empty_object = 1;
29353451Speter    }
29453451Speter  if (lp)
29553451Speter    {
29653451Speter      h->object_base = h->next_free = (char *)(obj);
29753451Speter      h->chunk_limit = lp->limit;
29853451Speter      h->chunk = lp;
29953451Speter    }
30053451Speter  else if (obj != 0)
30153451Speter    /* obj is not in any of the chunks! */
30253451Speter    abort ();
30353451Speter}
30453451Speter
30553451Speter/* This function is used from ANSI code.  */
30653451Speter
30753451Spetervoid
30853451Speterobstack_free (h, obj)
30953451Speter     struct obstack *h;
31053451Speter     POINTER obj;
31153451Speter{
31253451Speter  register struct _obstack_chunk*  lp;	/* below addr of any objects in this chunk */
31353451Speter  register struct _obstack_chunk*  plp;	/* point to previous chunk if any */
31453451Speter
31553451Speter  lp = h->chunk;
31653451Speter  /* We use >= because there cannot be an object at the beginning of a chunk.
31753451Speter     But there can be an empty object at that address
31853451Speter     at the end of another chunk.  */
31953451Speter  while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
32053451Speter    {
32153451Speter      plp = lp->prev;
32253451Speter      CALL_FREEFUN (h, lp);
32353451Speter      lp = plp;
32453451Speter      /* If we switch chunks, we can't tell whether the new current
32553451Speter	 chunk contains an empty object, so assume that it may.  */
32653451Speter      h->maybe_empty_object = 1;
32753451Speter    }
32853451Speter  if (lp)
32953451Speter    {
33053451Speter      h->object_base = h->next_free = (char *)(obj);
33153451Speter      h->chunk_limit = lp->limit;
33253451Speter      h->chunk = lp;
33353451Speter    }
33453451Speter  else if (obj != 0)
33553451Speter    /* obj is not in any of the chunks! */
33653451Speter    abort ();
33753451Speter}
33853451Speter
33953451Speter#if 0
34053451Speter/* These are now turned off because the applications do not use it
34153451Speter   and it uses bcopy via obstack_grow, which causes trouble on sysV.  */
34253451Speter
34353451Speter/* Now define the functional versions of the obstack macros.
34453451Speter   Define them to simply use the corresponding macros to do the job.  */
34553451Speter
34653451Speter#ifdef __STDC__
34753451Speter/* These function definitions do not work with non-ANSI preprocessors;
34853451Speter   they won't pass through the macro names in parentheses.  */
34953451Speter
35053451Speter/* The function names appear in parentheses in order to prevent
35153451Speter   the macro-definitions of the names from being expanded there.  */
35253451Speter
35353451SpeterPOINTER (obstack_base) (obstack)
35453451Speter     struct obstack *obstack;
35553451Speter{
35653451Speter  return obstack_base (obstack);
35753451Speter}
35853451Speter
35953451SpeterPOINTER (obstack_next_free) (obstack)
36053451Speter     struct obstack *obstack;
36153451Speter{
36253451Speter  return obstack_next_free (obstack);
36353451Speter}
36453451Speter
36553451Speterint (obstack_object_size) (obstack)
36653451Speter     struct obstack *obstack;
36753451Speter{
36853451Speter  return obstack_object_size (obstack);
36953451Speter}
37053451Speter
37153451Speterint (obstack_room) (obstack)
37253451Speter     struct obstack *obstack;
37353451Speter{
37453451Speter  return obstack_room (obstack);
37553451Speter}
37653451Speter
37753451Spetervoid (obstack_grow) (obstack, pointer, length)
37853451Speter     struct obstack *obstack;
37953451Speter     POINTER pointer;
38053451Speter     int length;
38153451Speter{
38253451Speter  obstack_grow (obstack, pointer, length);
38353451Speter}
38453451Speter
38553451Spetervoid (obstack_grow0) (obstack, pointer, length)
38653451Speter     struct obstack *obstack;
38753451Speter     POINTER pointer;
38853451Speter     int length;
38953451Speter{
39053451Speter  obstack_grow0 (obstack, pointer, length);
39153451Speter}
39253451Speter
39353451Spetervoid (obstack_1grow) (obstack, character)
39453451Speter     struct obstack *obstack;
39553451Speter     int character;
39653451Speter{
39753451Speter  obstack_1grow (obstack, character);
39853451Speter}
39953451Speter
40053451Spetervoid (obstack_blank) (obstack, length)
40153451Speter     struct obstack *obstack;
40253451Speter     int length;
40353451Speter{
40453451Speter  obstack_blank (obstack, length);
40553451Speter}
40653451Speter
40753451Spetervoid (obstack_1grow_fast) (obstack, character)
40853451Speter     struct obstack *obstack;
40953451Speter     int character;
41053451Speter{
41153451Speter  obstack_1grow_fast (obstack, character);
41253451Speter}
41353451Speter
41453451Spetervoid (obstack_blank_fast) (obstack, length)
41553451Speter     struct obstack *obstack;
41653451Speter     int length;
41753451Speter{
41853451Speter  obstack_blank_fast (obstack, length);
41953451Speter}
42053451Speter
42153451SpeterPOINTER (obstack_finish) (obstack)
42253451Speter     struct obstack *obstack;
42353451Speter{
42453451Speter  return obstack_finish (obstack);
42553451Speter}
42653451Speter
42753451SpeterPOINTER (obstack_alloc) (obstack, length)
42853451Speter     struct obstack *obstack;
42953451Speter     int length;
43053451Speter{
43153451Speter  return obstack_alloc (obstack, length);
43253451Speter}
43353451Speter
43453451SpeterPOINTER (obstack_copy) (obstack, pointer, length)
43553451Speter     struct obstack *obstack;
43653451Speter     POINTER pointer;
43753451Speter     int length;
43853451Speter{
43953451Speter  return obstack_copy (obstack, pointer, length);
44053451Speter}
44153451Speter
44253451SpeterPOINTER (obstack_copy0) (obstack, pointer, length)
44353451Speter     struct obstack *obstack;
44453451Speter     POINTER pointer;
44553451Speter     int length;
44653451Speter{
44753451Speter  return obstack_copy0 (obstack, pointer, length);
44853451Speter}
44953451Speter
45053451Speter#endif /* __STDC__ */
45153451Speter
45253451Speter#endif /* 0 */
45353451Speter
45453451Speter#endif	/* _LIBC or not __GNU_LIBRARY__.  */
455