objalloc.h revision 33965
133965Sjdp/* objalloc.h -- routines to allocate memory for objects
233965Sjdp   Copyright 1997 Free Software Foundation, Inc.
333965Sjdp   Written by Ian Lance Taylor, Cygnus Solutions.
433965Sjdp
533965SjdpThis program is free software; you can redistribute it and/or modify it
633965Sjdpunder the terms of the GNU General Public License as published by the
733965SjdpFree Software Foundation; either version 2, or (at your option) any
833965Sjdplater version.
933965Sjdp
1033965SjdpThis program is distributed in the hope that it will be useful,
1133965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1233965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1333965SjdpGNU General Public License for more details.
1433965Sjdp
1533965SjdpYou should have received a copy of the GNU General Public License
1633965Sjdpalong with this program; if not, write to the Free Software
1733965SjdpFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
1833965Sjdp
1933965Sjdp#ifndef OBJALLOC_H
2033965Sjdp#define OBJALLOC_H
2133965Sjdp
2233965Sjdp#include "ansidecl.h"
2333965Sjdp
2433965Sjdp/* These routines allocate space for an object.  The assumption is
2533965Sjdp   that the object will want to allocate space as it goes along, but
2633965Sjdp   will never want to free any particular block.  There is a function
2733965Sjdp   to free a block, which also frees all more recently allocated
2833965Sjdp   blocks.  There is also a function to free all the allocated space.
2933965Sjdp
3033965Sjdp   This is essentially a specialization of obstacks.  The main
3133965Sjdp   difference is that a block may not be allocated a bit at a time.
3233965Sjdp   Another difference is that these routines are always built on top
3333965Sjdp   of malloc, and always pass an malloc failure back to the caller,
3433965Sjdp   unlike more recent versions of obstacks.  */
3533965Sjdp
3633965Sjdp/* This is what an objalloc structure looks like.  Callers should not
3733965Sjdp   refer to these fields, nor should they allocate these structure
3833965Sjdp   themselves.  Instead, they should only create them via
3933965Sjdp   objalloc_init, and only access them via the functions and macros
4033965Sjdp   listed below.  The structure is only defined here so that we can
4133965Sjdp   access it via macros.  */
4233965Sjdp
4333965Sjdpstruct objalloc
4433965Sjdp{
4533965Sjdp  char *current_ptr;
4633965Sjdp  unsigned int current_space;
4733965Sjdp  PTR chunks;
4833965Sjdp};
4933965Sjdp
5033965Sjdp/* Work out the required alignment.  */
5133965Sjdp
5233965Sjdpstruct objalloc_align { char x; double d; };
5333965Sjdp
5433965Sjdp#if defined (__STDC__) && __STDC__
5533965Sjdp#ifndef offsetof
5633965Sjdp#include <stddef.h>
5733965Sjdp#endif
5833965Sjdp#define OBJALLOC_ALIGN \
5933965Sjdp  ((ptrdiff_t) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0))
6033965Sjdp#else
6133965Sjdp#define OBJALLOC_ALIGN \
6233965Sjdp  ((long) ((char *) &((struct objalloc_align *) 0)->d - (char *) 0))
6333965Sjdp#endif
6433965Sjdp
6533965Sjdp/* Create an objalloc structure.  Returns NULL if malloc fails.  */
6633965Sjdp
6733965Sjdpextern struct objalloc *objalloc_create PARAMS ((void));
6833965Sjdp
6933965Sjdp/* Allocate space from an objalloc structure.  Returns NULL if malloc
7033965Sjdp   fails.  */
7133965Sjdp
7233965Sjdpextern PTR _objalloc_alloc PARAMS ((struct objalloc *, unsigned long));
7333965Sjdp
7433965Sjdp/* The macro version of objalloc_alloc.  We only define this if using
7533965Sjdp   gcc, because otherwise we would have to evaluate the arguments
7633965Sjdp   multiple times, or use a temporary field as obstack.h does.  */
7733965Sjdp
7833965Sjdp#if defined (__GNUC__) && defined (__STDC__) && __STDC__
7933965Sjdp
8033965Sjdp/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
8133965Sjdp   does not implement __extension__.  But that compiler doesn't define
8233965Sjdp   __GNUC_MINOR__.  */
8333965Sjdp#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
8433965Sjdp#define __extension__
8533965Sjdp#endif
8633965Sjdp
8733965Sjdp#define objalloc_alloc(o, l)						\
8833965Sjdp  __extension__								\
8933965Sjdp  ({ struct objalloc *__o = (o);					\
9033965Sjdp     unsigned long __len = (l);						\
9133965Sjdp     if (__len == 0)							\
9233965Sjdp       __len = 1;							\
9333965Sjdp     __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);	\
9433965Sjdp     (__len <= __o->current_space					\
9533965Sjdp      ? (__o->current_ptr += __len,					\
9633965Sjdp	 __o->current_space -= __len,					\
9733965Sjdp	 (PTR) (__o->current_ptr - __len))				\
9833965Sjdp      : _objalloc_alloc (__o, __len)); })
9933965Sjdp
10033965Sjdp#else /* ! __GNUC__ */
10133965Sjdp
10233965Sjdp#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
10333965Sjdp
10433965Sjdp#endif /* ! __GNUC__ */
10533965Sjdp
10633965Sjdp/* Free an entire objalloc structure.  */
10733965Sjdp
10833965Sjdpextern void objalloc_free PARAMS ((struct objalloc *));
10933965Sjdp
11033965Sjdp/* Free a block allocated by objalloc_alloc.  This also frees all more
11133965Sjdp   recently allocated blocks.  */
11233965Sjdp
11333965Sjdpextern void objalloc_free_block PARAMS ((struct objalloc *, PTR));
11433965Sjdp
11533965Sjdp#endif /* OBJALLOC_H */
116